Skip to content

Clean up Abstractions / use HashData #1451

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

Merged
merged 2 commits into from
Jul 23, 2024
Merged
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
79 changes: 48 additions & 31 deletions src/Renci.SshNet/Abstractions/CryptoAbstraction.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System;
using System.Security.Cryptography;

namespace Renci.SshNet.Abstractions
{
internal static class CryptoAbstraction
{
private static readonly System.Security.Cryptography.RandomNumberGenerator Randomizer = CreateRandomNumberGenerator();
private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create();

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

/// <summary>
/// Fills an array of bytes with a cryptographically strong random sequence of values.
/// </summary>
/// <param name="data">The array to fill with cryptographically strong random bytes.</param>
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <see langword="null"/>.</exception>
/// <remarks>
/// The length of the byte array determines how many random bytes are produced.
/// </remarks>
public static void GenerateRandom(byte[] data)
{
Randomizer.GetBytes(data);
}

public static System.Security.Cryptography.RandomNumberGenerator CreateRandomNumberGenerator()
{
return System.Security.Cryptography.RandomNumberGenerator.Create();
}

public static System.Security.Cryptography.MD5 CreateMD5()
public static byte[] HashMD5(byte[] source)
{
return System.Security.Cryptography.MD5.Create();
#if NET
return MD5.HashData(source);
#else
using (var md5 = MD5.Create())
{
return md5.ComputeHash(source);
}
#endif
}

public static System.Security.Cryptography.SHA1 CreateSHA1()
public static byte[] HashSHA1(byte[] source)
{
return System.Security.Cryptography.SHA1.Create();
#if NET
return SHA1.HashData(source);
#else
using (var sha1 = SHA1.Create())
{
return sha1.ComputeHash(source);
}
#endif
}

public static System.Security.Cryptography.SHA256 CreateSHA256()
public static byte[] HashSHA256(byte[] source)
{
return System.Security.Cryptography.SHA256.Create();
#if NET
return SHA256.HashData(source);
#else
using (var sha256 = SHA256.Create())
{
return sha256.ComputeHash(source);
}
#endif
}

public static System.Security.Cryptography.SHA384 CreateSHA384()
public static byte[] HashSHA384(byte[] source)
{
return System.Security.Cryptography.SHA384.Create();
#if NET
return SHA384.HashData(source);
#else
using (var sha384 = SHA384.Create())
{
return sha384.ComputeHash(source);
}
#endif
}

public static System.Security.Cryptography.SHA512 CreateSHA512()
public static byte[] HashSHA512(byte[] source)
{
return System.Security.Cryptography.SHA512.Create();
#if NET
return SHA512.HashData(source);
#else
using (var sha512 = SHA512.Create())
{
return sha512.ComputeHash(source);
}
#endif
}
}
}
16 changes: 0 additions & 16 deletions src/Renci.SshNet/Abstractions/ReflectionAbstraction.cs

This file was deleted.

3 changes: 1 addition & 2 deletions src/Renci.SshNet/Common/BigInteger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ public static BigInteger PositiveMod(BigInteger dividend, BigInteger divisor)
/// <returns>A random number of the specified length.</returns>
public static BigInteger Random(int bitLength)
{
var bytesArray = new byte[(bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0)];
CryptoAbstraction.GenerateRandom(bytesArray);
var bytesArray = CryptoAbstraction.GenerateRandom((bitLength / 8) + (((bitLength % 8) > 0) ? 1 : 0));
bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F); // Ensure not a negative value
return new BigInteger(bytesArray);
}
Expand Down
10 changes: 2 additions & 8 deletions src/Renci.SshNet/Common/HostKeyEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,11 @@ public HostKeyEventArgs(KeyHostAlgorithm host)
HostKeyName = host.Name;
KeyLength = host.Key.KeyLength;

_lazyFingerPrint = new Lazy<byte[]>(() =>
{
using var md5 = CryptoAbstraction.CreateMD5();
return md5.ComputeHash(HostKey);
});
_lazyFingerPrint = new Lazy<byte[]>(() => CryptoAbstraction.HashMD5(HostKey));

_lazyFingerPrintSHA256 = new Lazy<string>(() =>
{
using var sha256 = CryptoAbstraction.CreateSHA256();

return Convert.ToBase64String(sha256.ComputeHash(HostKey))
return Convert.ToBase64String(CryptoAbstraction.HashSHA256(HostKey))
#if NET || NETSTANDARD2_1_OR_GREATER
.Replace("=", string.Empty, StringComparison.Ordinal);
#else
Expand Down
6 changes: 2 additions & 4 deletions src/Renci.SshNet/Messages/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex
var paddingLength = GetPaddingLength(paddingMultiplier, excludePacketLengthFieldWhenPadding ? packetLength - 4 : packetLength);

// add padding bytes
var paddingBytes = new byte[paddingLength];
CryptoAbstraction.GenerateRandom(paddingBytes);
var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength);
sshDataStream.Write(paddingBytes, 0, paddingLength);

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

// add padding bytes
var paddingBytes = new byte[paddingLength];
CryptoAbstraction.GenerateRandom(paddingBytes);
var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength);
sshDataStream.Write(paddingBytes, 0, paddingLength);

return sshDataStream.ToArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ public class KeyExchangeInitMessage : Message, IKeyExchangedAllowed
/// </summary>
public KeyExchangeInitMessage()
{
var cookie = new byte[16];
CryptoAbstraction.GenerateRandom(cookie);
Cookie = cookie;
Cookie = CryptoAbstraction.GenerateRandom(16);
}

#region Message Properties
Expand Down
9 changes: 6 additions & 3 deletions src/Renci.SshNet/PrivateKeyFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Text;
using System.Text.RegularExpressions;

using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Security;
using Renci.SshNet.Security.Cryptography;
Expand Down Expand Up @@ -380,7 +379,8 @@ private static byte[] GetCipherKey(string passphrase, int length)
{
var cipherKey = new List<byte>();

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

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

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

var cipherKey = new List<byte>();

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

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

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

Expand Down
2 changes: 1 addition & 1 deletion src/Renci.SshNet/Security/Cryptography/Bcrypt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ public void Hash(byte[] hpass, byte[] hsalt, byte[] output)
/// <param name="output"></param>
public void Pbkdf(byte[] password, byte[] salt, int rounds, byte[] output)
{
using (var sha512 = CryptoAbstraction.CreateSHA512())
using (var sha512 = SHA512.Create())
{
int nblocks = (output.Length + 31) / 32;
byte[] hpass = sha512.ComputeHash(password);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Security.Cryptography;

using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;

namespace Renci.SshNet.Security.Cryptography
Expand Down Expand Up @@ -29,7 +28,7 @@ public DsaDigitalSignature(DsaKey key)

_key = key;

_hash = CryptoAbstraction.CreateSHA1();
_hash = SHA1.Create();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha1 = CryptoAbstraction.CreateSHA1())
{
return sha1.ComputeHash(hashData, 0, hashData.Length);
}
return CryptoAbstraction.HashSHA1(hashData);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha256 = CryptoAbstraction.CreateSHA256())
{
return sha256.ComputeHash(hashData);
}
return CryptoAbstraction.HashSHA256(hashData);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha1 = CryptoAbstraction.CreateSHA1())
{
return sha1.ComputeHash(hashData, 0, hashData.Length);
}
return CryptoAbstraction.HashSHA1(hashData);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha256 = CryptoAbstraction.CreateSHA256())
{
return sha256.ComputeHash(hashData);
}
return CryptoAbstraction.HashSHA256(hashData);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha512 = CryptoAbstraction.CreateSHA512())
{
return sha512.ComputeHash(hashData);
}
return CryptoAbstraction.HashSHA512(hashData);
}
}
}
5 changes: 1 addition & 4 deletions src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ public override void Finish()
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha256 = CryptoAbstraction.CreateSHA256())
{
return sha256.ComputeHash(hashData, 0, hashData.Length);
}
return CryptoAbstraction.HashSHA256(hashData);
}

private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs<KeyExchangeEcdhReplyMessage> e)
Expand Down
7 changes: 2 additions & 5 deletions src/Renci.SshNet/Security/KeyExchangeECDH256.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;

using Renci.SshNet.Abstractions;
Expand Down Expand Up @@ -46,10 +46,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha256 = CryptoAbstraction.CreateSHA256())
{
return sha256.ComputeHash(hashData, 0, hashData.Length);
}
return CryptoAbstraction.HashSHA256(hashData);
}
}
}
7 changes: 2 additions & 5 deletions src/Renci.SshNet/Security/KeyExchangeECDH384.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;

using Renci.SshNet.Abstractions;
Expand Down Expand Up @@ -46,10 +46,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha384 = CryptoAbstraction.CreateSHA384())
{
return sha384.ComputeHash(hashData, 0, hashData.Length);
}
return CryptoAbstraction.HashSHA384(hashData);
}
}
}
7 changes: 2 additions & 5 deletions src/Renci.SshNet/Security/KeyExchangeECDH521.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;

using Renci.SshNet.Abstractions;
Expand Down Expand Up @@ -46,10 +46,7 @@ protected override int HashSize
/// </returns>
protected override byte[] Hash(byte[] hashData)
{
using (var sha512 = CryptoAbstraction.CreateSHA512())
{
return sha512.ComputeHash(hashData, 0, hashData.Length);
}
return CryptoAbstraction.HashSHA512(hashData);
}
}
}
Loading