Skip to content
Draft
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
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,9 @@ dotnet_diagnostic.CA1848.severity = silent
# By default, this diagnostic is only reported for private members.
dotnet_code_quality.CA1859.api_surface = private,internal

# CA1873: Evaluation of this argument may be expensive and unnecessary if logging is disabled
dotnet_diagnostic.CA1873.severity = suggestion

# CA2208: Instantiate argument exceptions correctly
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2208
#
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,33 @@ jobs:
uses: actions/setup-dotnet@v4

- name: Build Unit Tests .NET
run: dotnet build -f net9.0 test/Renci.SshNet.Tests/
run: dotnet build -f net10.0 test/Renci.SshNet.Tests/

- name: Build IntegrationTests .NET
run: dotnet build -f net9.0 test/Renci.SshNet.IntegrationTests/
run: dotnet build -f net10.0 test/Renci.SshNet.IntegrationTests/

- name: Run Unit Tests .NET
run: |
dotnet test \
-f net9.0 \
-f net10.0 \
--no-build \
--logger "console;verbosity=normal" \
--logger GitHubActions \
-p:CollectCoverage=true \
-p:CoverletOutputFormat=cobertura \
-p:CoverletOutput=../../coverlet/linux_unit_test_net_9_coverage.xml \
-p:CoverletOutput=../../coverlet/linux_unit_test_net_10_coverage.xml \
test/Renci.SshNet.Tests/

- name: Run Integration Tests .NET
run: |
dotnet test \
-f net9.0 \
-f net10.0 \
--no-build \
--logger "console;verbosity=normal" \
--logger GitHubActions \
-p:CollectCoverage=true \
-p:CoverletOutputFormat=cobertura \
-p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage.xml \
-p:CoverletOutput=../../coverlet/linux_integration_test_net_10_coverage.xml \
test/Renci.SshNet.IntegrationTests/

- name: Archive Coverlet Results
Expand Down Expand Up @@ -82,13 +82,13 @@ jobs:
- name: Run Unit Tests .NET
run: |
dotnet test `
-f net9.0 `
-f net10.0 `
--no-build `
--logger "console;verbosity=normal" `
--logger GitHubActions `
-p:CollectCoverage=true `
-p:CoverletOutputFormat=cobertura `
-p:CoverletOutput=../../coverlet/windows_unit_test_net_9_coverage.xml `
-p:CoverletOutput=../../coverlet/windows_unit_test_net_10_coverage.xml `
test/Renci.SshNet.Tests/

- name: Run Unit Tests .NET Framework
Expand Down
4 changes: 2 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.210" />
<!-- Should stay on LTS .NET releases. -->
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.7" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="MSTest" Version="3.10.0" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Nerdbank.GitVersioning" Version="3.7.115" />
Expand All @@ -23,4 +23,4 @@
<PackageVersion Include="System.Formats.Asn1" Version="8.0.2" />
<PackageVersion Include="Testcontainers" Version="4.6.0" />
</ItemGroup>
</Project>
</Project>
3 changes: 2 additions & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"sdk": {
"version": "9.0.300",
"version": "10.0.100-rc.1.25451.107",
"allowPrerelease": true,
"rollForward": "latestFeature"
}
}
34 changes: 34 additions & 0 deletions src/Renci.SshNet/Abstractions/ConvertExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#nullable enable
#if !NET
using System.Text;
#endif

namespace System
{
internal static class ConvertExtensions
{
extension(Convert)
{
#if !NET
public static byte[] FromHexString(string s)
{
return Org.BouncyCastle.Utilities.Encoders.Hex.Decode(s);
}

public static string ToHexString(byte[] inArray)
{
ArgumentNullException.ThrowIfNull(inArray);

var builder = new StringBuilder(inArray.Length * 2);

foreach (var b in inArray)
{
builder.Append(b.ToString("X2"));
}

return builder.ToString();
}
#endif
}
}
}
72 changes: 0 additions & 72 deletions src/Renci.SshNet/Abstractions/CryptoAbstraction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,77 +10,5 @@ internal static class CryptoAbstraction
private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create();

internal static readonly SecureRandom SecureRandom = new SecureRandom(new CryptoApiRandomGenerator(Randomizer));

/// <summary>
/// Generates a <see cref="byte"/> array of the specified length, and fills it with a
/// cryptographically strong random sequence of values.
/// </summary>
/// <param name="length">The length of the array generate.</param>
public static byte[] GenerateRandom(int length)
{
var random = new byte[length];
Randomizer.GetBytes(random);
return random;
}

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

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

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

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

public static byte[] HashSHA512(byte[] source)
{
#if NET
return SHA512.HashData(source);
#else
using (var sha512 = SHA512.Create())
{
return sha512.ComputeHash(source);
}
#endif
}
}
}
19 changes: 19 additions & 0 deletions src/Renci.SshNet/Abstractions/DateTimeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#nullable enable
namespace System
{
internal static class DateTimeExtensions
{
extension(DateTime)
{
#if !NET
public static DateTime UnixEpoch
{
get
{
return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
}
}
#endif
}
}
}
19 changes: 19 additions & 0 deletions src/Renci.SshNet/Abstractions/MD5Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#nullable enable
namespace System.Security.Cryptography
{
internal static class MD5Extensions
{
extension(MD5)
{
#if !NET
public static byte[] HashData(byte[] source)
{
using (var md5 = MD5.Create())
{
return md5.ComputeHash(source);
}
}
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#nullable enable
namespace System.Security.Cryptography
{
internal static class RandomNumberGeneratorExtensions
{
#if !NET
private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create();
#endif

extension(RandomNumberGenerator)
{
#if !NET
public static byte[] GetBytes(int length)
{
var random = new byte[length];
Randomizer.GetBytes(random);
return random;
}
#endif
}
}
}
18 changes: 18 additions & 0 deletions src/Renci.SshNet/Abstractions/SHA1Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace System.Security.Cryptography
{
internal static class SHA1Extensions
{
extension(SHA1)
{
#if !NET
public static byte[] HashData(byte[] source)
{
using (var sha1 = SHA1.Create())
{
return sha1.ComputeHash(source);
}
}
#endif
}
}
}
19 changes: 19 additions & 0 deletions src/Renci.SshNet/Abstractions/SHA256Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#nullable enable
namespace System.Security.Cryptography
{
internal static class SHA256Extensions
{
extension(SHA256)
{
#if !NET
public static byte[] HashData(byte[] source)
{
using (var sha256 = SHA256.Create())
{
return sha256.ComputeHash(source);
}
}
#endif
}
}
}
19 changes: 19 additions & 0 deletions src/Renci.SshNet/Abstractions/SHA384Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#nullable enable
namespace System.Security.Cryptography
{
internal static class SHA384Extensions
{
extension(SHA384)
{
#if !NET
public static byte[] HashData(byte[] source)
{
using (var sha384 = SHA384.Create())
{
return sha384.ComputeHash(source);
}
}
#endif
}
}
}
19 changes: 19 additions & 0 deletions src/Renci.SshNet/Abstractions/SHA512Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#nullable enable
namespace System.Security.Cryptography
{
internal static class SHA512Extensions
{
extension(SHA512)
{
#if !NET
public static byte[] HashData(byte[] source)
{
using (var sha512 = SHA512.Create())
{
return sha512.ComputeHash(source);
}
}
#endif
}
}
}
35 changes: 35 additions & 0 deletions src/Renci.SshNet/Abstractions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#nullable enable
#if NETSTANDARD2_0 || NETFRAMEWORK
using System.Collections.Generic;
#endif

namespace System
{
internal static class StringExtensions
{
extension(string text)
{
#if NETSTANDARD2_0 || NETFRAMEWORK
public static string Join(char separator, params string?[] value)
{
return string.Join(separator.ToString(), value);
}

public static string Join(char separator, IEnumerable<string?> value)
{
return string.Join(separator.ToString(), value);
}

public static string Join(char separator, string?[] value, int startIndex, int count)
{
return string.Join(separator.ToString(), value, startIndex, count);
}

public int IndexOf(char value, StringComparison comparisonType)
{
return text.IndexOf(value.ToString(), comparisonType);
}
#endif
}
}
}
Loading