Skip to content

Commit 4cc1278

Browse files
mus65Rob-Hague
andauthored
Clean up Abstractions / use HashData (#1451)
* Clean up Abstractions / use HashData - replace usages of GenerateRandom(byte[]) with GenerateRandom(int) - remove Create() functions and make use of static HashData methods on .NET 6+, see https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1850 - Remove unused ReflectionAbstraction * Use Abstractions for HashData Co-authored-by: Robert Hague <[email protected]> --------- Co-authored-by: Robert Hague <[email protected]>
1 parent 8ea108a commit 4cc1278

19 files changed

+77
-110
lines changed

Diff for: src/Renci.SshNet/Abstractions/CryptoAbstraction.cs

+48-31
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
using System;
1+
using System.Security.Cryptography;
22

33
namespace Renci.SshNet.Abstractions
44
{
55
internal static class CryptoAbstraction
66
{
7-
private static readonly System.Security.Cryptography.RandomNumberGenerator Randomizer = CreateRandomNumberGenerator();
7+
private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create();
88

99
/// <summary>
1010
/// Generates a <see cref="byte"/> array of the specified length, and fills it with a
@@ -14,51 +14,68 @@ internal static class CryptoAbstraction
1414
public static byte[] GenerateRandom(int length)
1515
{
1616
var random = new byte[length];
17-
GenerateRandom(random);
17+
Randomizer.GetBytes(random);
1818
return random;
1919
}
2020

21-
/// <summary>
22-
/// Fills an array of bytes with a cryptographically strong random sequence of values.
23-
/// </summary>
24-
/// <param name="data">The array to fill with cryptographically strong random bytes.</param>
25-
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
26-
/// <remarks>
27-
/// The length of the byte array determines how many random bytes are produced.
28-
/// </remarks>
29-
public static void GenerateRandom(byte[] data)
30-
{
31-
Randomizer.GetBytes(data);
32-
}
33-
34-
public static System.Security.Cryptography.RandomNumberGenerator CreateRandomNumberGenerator()
35-
{
36-
return System.Security.Cryptography.RandomNumberGenerator.Create();
37-
}
38-
39-
public static System.Security.Cryptography.MD5 CreateMD5()
21+
public static byte[] HashMD5(byte[] source)
4022
{
41-
return System.Security.Cryptography.MD5.Create();
23+
#if NET
24+
return MD5.HashData(source);
25+
#else
26+
using (var md5 = MD5.Create())
27+
{
28+
return md5.ComputeHash(source);
29+
}
30+
#endif
4231
}
4332

44-
public static System.Security.Cryptography.SHA1 CreateSHA1()
33+
public static byte[] HashSHA1(byte[] source)
4534
{
46-
return System.Security.Cryptography.SHA1.Create();
35+
#if NET
36+
return SHA1.HashData(source);
37+
#else
38+
using (var sha1 = SHA1.Create())
39+
{
40+
return sha1.ComputeHash(source);
41+
}
42+
#endif
4743
}
4844

49-
public static System.Security.Cryptography.SHA256 CreateSHA256()
45+
public static byte[] HashSHA256(byte[] source)
5046
{
51-
return System.Security.Cryptography.SHA256.Create();
47+
#if NET
48+
return SHA256.HashData(source);
49+
#else
50+
using (var sha256 = SHA256.Create())
51+
{
52+
return sha256.ComputeHash(source);
53+
}
54+
#endif
5255
}
5356

54-
public static System.Security.Cryptography.SHA384 CreateSHA384()
57+
public static byte[] HashSHA384(byte[] source)
5558
{
56-
return System.Security.Cryptography.SHA384.Create();
59+
#if NET
60+
return SHA384.HashData(source);
61+
#else
62+
using (var sha384 = SHA384.Create())
63+
{
64+
return sha384.ComputeHash(source);
65+
}
66+
#endif
5767
}
5868

59-
public static System.Security.Cryptography.SHA512 CreateSHA512()
69+
public static byte[] HashSHA512(byte[] source)
6070
{
61-
return System.Security.Cryptography.SHA512.Create();
71+
#if NET
72+
return SHA512.HashData(source);
73+
#else
74+
using (var sha512 = SHA512.Create())
75+
{
76+
return sha512.ComputeHash(source);
77+
}
78+
#endif
6279
}
6380
}
6481
}

Diff for: src/Renci.SshNet/Abstractions/ReflectionAbstraction.cs

-16
This file was deleted.

Diff for: src/Renci.SshNet/Common/BigInteger.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,7 @@ public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor)
179179
/// <returns>A random number of the specified length.</returns>
180180
public static BigInteger Random(int bitLength)
181181
{
182-
var bytesArray = new byte[(bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0)];
183-
CryptoAbstraction.GenerateRandom(bytesArray);
182+
var bytesArray = CryptoAbstraction.GenerateRandom((bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0));
184183
bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value
185184
return new BigInteger(bytesArray);
186185
}

Diff for: src/Renci.SshNet/Common/HostKeyEventArgs.cs

+2-8
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,11 @@ public HostKeyEventArgs(KeyHostAlgorithm host)
100100
HostKeyName = host.Name;
101101
KeyLength = host.Key.KeyLength;
102102

103-
_lazyFingerPrint = new Lazy<byte[]>(() =>
104-
{
105-
using var md5 = CryptoAbstraction.CreateMD5();
106-
return md5.ComputeHash(HostKey);
107-
});
103+
_lazyFingerPrint = new Lazy<byte[]>(() => CryptoAbstraction.HashMD5(HostKey));
108104

109105
_lazyFingerPrintSHA256 = new Lazy<string>(() =>
110106
{
111-
using var sha256 = CryptoAbstraction.CreateSHA256();
112-
113-
return Convert.ToBase64String(sha256.ComputeHash(HostKey))
107+
return Convert.ToBase64String(CryptoAbstraction.HashSHA256(HostKey))
114108
#if NET || NETSTANDARD2_1_OR_GREATER
115109
.Replace("=", string.Empty, StringComparison.Ordinal);
116110
#else

Diff for: src/Renci.SshNet/Messages/Message.cs

+2-4
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex
8383
var paddingLength = GetPaddingLength(paddingMultiplier, excludePacketLengthFieldWhenPadding ? packetLength - 4 : packetLength);
8484

8585
// add padding bytes
86-
var paddingBytes = new byte[paddingLength];
87-
CryptoAbstraction.GenerateRandom(paddingBytes);
86+
var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength);
8887
sshDataStream.Write(paddingBytes, 0, paddingLength);
8988

9089
var packetDataLength = GetPacketDataLength(messageLength, paddingLength);
@@ -128,8 +127,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex
128127
WriteBytes(sshDataStream);
129128

130129
// add padding bytes
131-
var paddingBytes = new byte[paddingLength];
132-
CryptoAbstraction.GenerateRandom(paddingBytes);
130+
var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength);
133131
sshDataStream.Write(paddingBytes, 0, paddingLength);
134132

135133
return sshDataStream.ToArray();

Diff for: src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ public class KeyExchangeInitMessage : Message, IKeyExchangedAllowed
1212
/// </summary>
1313
public KeyExchangeInitMessage()
1414
{
15-
var cookie = new byte[16];
16-
CryptoAbstraction.GenerateRandom(cookie);
17-
Cookie = cookie;
15+
Cookie = CryptoAbstraction.GenerateRandom(16);
1816
}
1917

2018
#region Message Properties

Diff for: src/Renci.SshNet/PrivateKeyFile.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.Text;
88
using System.Text.RegularExpressions;
99

10-
using Renci.SshNet.Abstractions;
1110
using Renci.SshNet.Common;
1211
using Renci.SshNet.Security;
1312
using Renci.SshNet.Security.Cryptography;
@@ -380,7 +379,8 @@ private static byte[] GetCipherKey(string passphrase, int length)
380379
{
381380
var cipherKey = new List<byte>();
382381

383-
using (var md5 = CryptoAbstraction.CreateMD5())
382+
#pragma warning disable CA1850 // Prefer static HashData method; We'll reuse the object on lower targets.
383+
using (var md5 = MD5.Create())
384384
{
385385
var passwordBytes = Encoding.UTF8.GetBytes(passphrase);
386386

@@ -394,6 +394,7 @@ private static byte[] GetCipherKey(string passphrase, int length)
394394
cipherKey.AddRange(hash);
395395
}
396396
}
397+
#pragma warning restore CA1850 // Prefer static HashData method
397398

398399
return cipherKey.ToArray().Take(length);
399400
}
@@ -426,7 +427,8 @@ private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, strin
426427

427428
var cipherKey = new List<byte>();
428429

429-
using (var md5 = CryptoAbstraction.CreateMD5())
430+
#pragma warning disable CA1850 // Prefer static HashData method; We'll reuse the object on lower targets.
431+
using (var md5 = MD5.Create())
430432
{
431433
var passwordBytes = Encoding.UTF8.GetBytes(passPhrase);
432434

@@ -443,6 +445,7 @@ private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, strin
443445
cipherKey.AddRange(hash);
444446
}
445447
}
448+
#pragma warning restore CA1850 // Prefer static HashData method
446449

447450
var cipher = cipherInfo.Cipher(cipherKey.ToArray(), binarySalt);
448451

Diff for: src/Renci.SshNet/Security/Cryptography/Bcrypt.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ public void Hash(byte[] hpass, byte[] hsalt, byte[] output)
852852
/// <param name="output"></param>
853853
public void Pbkdf(byte[] password, byte[] salt, int rounds, byte[] output)
854854
{
855-
using (var sha512 = CryptoAbstraction.CreateSHA512())
855+
using (var sha512 = SHA512.Create())
856856
{
857857
int nblocks = (output.Length + 31) / 32;
858858
byte[] hpass = sha512.ComputeHash(password);

Diff for: src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Security.Cryptography;
33

4-
using Renci.SshNet.Abstractions;
54
using Renci.SshNet.Common;
65

76
namespace Renci.SshNet.Security.Cryptography
@@ -29,7 +28,7 @@ public DsaDigitalSignature(DsaKey key)
2928

3029
_key = key;
3130

32-
_hash = CryptoAbstraction.CreateSHA1();
31+
_hash = SHA1.Create();
3332
}
3433

3534
/// <summary>

Diff for: src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha1.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ protected override int HashSize
3535
/// </returns>
3636
protected override byte[] Hash(byte[] hashData)
3737
{
38-
using (var sha1 = CryptoAbstraction.CreateSHA1())
39-
{
40-
return sha1.ComputeHash(hashData, 0, hashData.Length);
41-
}
38+
return CryptoAbstraction.HashSHA1(hashData);
4239
}
4340
}
4441
}

Diff for: src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ protected override int HashSize
3535
/// </returns>
3636
protected override byte[] Hash(byte[] hashData)
3737
{
38-
using (var sha256 = CryptoAbstraction.CreateSHA256())
39-
{
40-
return sha256.ComputeHash(hashData);
41-
}
38+
return CryptoAbstraction.HashSHA256(hashData);
4239
}
4340
}
4441
}

Diff for: src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha1.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ protected override int HashSize
2727
/// </returns>
2828
protected override byte[] Hash(byte[] hashData)
2929
{
30-
using (var sha1 = CryptoAbstraction.CreateSHA1())
31-
{
32-
return sha1.ComputeHash(hashData, 0, hashData.Length);
33-
}
30+
return CryptoAbstraction.HashSHA1(hashData);
3431
}
3532
}
3633
}

Diff for: src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha256.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ protected override int HashSize
2727
/// </returns>
2828
protected override byte[] Hash(byte[] hashData)
2929
{
30-
using (var sha256 = CryptoAbstraction.CreateSHA256())
31-
{
32-
return sha256.ComputeHash(hashData);
33-
}
30+
return CryptoAbstraction.HashSHA256(hashData);
3431
}
3532
}
3633
}

Diff for: src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupSha512.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ protected override int HashSize
2727
/// </returns>
2828
protected override byte[] Hash(byte[] hashData)
2929
{
30-
using (var sha512 = CryptoAbstraction.CreateSHA512())
31-
{
32-
return sha512.ComputeHash(hashData);
33-
}
30+
return CryptoAbstraction.HashSHA512(hashData);
3431
}
3532
}
3633
}

Diff for: src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,7 @@ public override void Finish()
6868
/// </returns>
6969
protected override byte[] Hash(byte[] hashData)
7070
{
71-
using (var sha256 = CryptoAbstraction.CreateSHA256())
72-
{
73-
return sha256.ComputeHash(hashData, 0, hashData.Length);
74-
}
71+
return CryptoAbstraction.HashSHA256(hashData);
7572
}
7673

7774
private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs<KeyExchangeEcdhReplyMessage> e)

Diff for: src/Renci.SshNet/Security/KeyExchangeECDH256.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Org.BouncyCastle.Asn1.Sec;
1+
using Org.BouncyCastle.Asn1.Sec;
22
using Org.BouncyCastle.Asn1.X9;
33

44
using Renci.SshNet.Abstractions;
@@ -46,10 +46,7 @@ protected override int HashSize
4646
/// </returns>
4747
protected override byte[] Hash(byte[] hashData)
4848
{
49-
using (var sha256 = CryptoAbstraction.CreateSHA256())
50-
{
51-
return sha256.ComputeHash(hashData, 0, hashData.Length);
52-
}
49+
return CryptoAbstraction.HashSHA256(hashData);
5350
}
5451
}
5552
}

Diff for: src/Renci.SshNet/Security/KeyExchangeECDH384.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Org.BouncyCastle.Asn1.Sec;
1+
using Org.BouncyCastle.Asn1.Sec;
22
using Org.BouncyCastle.Asn1.X9;
33

44
using Renci.SshNet.Abstractions;
@@ -46,10 +46,7 @@ protected override int HashSize
4646
/// </returns>
4747
protected override byte[] Hash(byte[] hashData)
4848
{
49-
using (var sha384 = CryptoAbstraction.CreateSHA384())
50-
{
51-
return sha384.ComputeHash(hashData, 0, hashData.Length);
52-
}
49+
return CryptoAbstraction.HashSHA384(hashData);
5350
}
5451
}
5552
}

Diff for: src/Renci.SshNet/Security/KeyExchangeECDH521.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Org.BouncyCastle.Asn1.Sec;
1+
using Org.BouncyCastle.Asn1.Sec;
22
using Org.BouncyCastle.Asn1.X9;
33

44
using Renci.SshNet.Abstractions;
@@ -46,10 +46,7 @@ protected override int HashSize
4646
/// </returns>
4747
protected override byte[] Hash(byte[] hashData)
4848
{
49-
using (var sha512 = CryptoAbstraction.CreateSHA512())
50-
{
51-
return sha512.ComputeHash(hashData, 0, hashData.Length);
52-
}
49+
return CryptoAbstraction.HashSHA512(hashData);
5350
}
5451
}
5552
}

0 commit comments

Comments
 (0)