Skip to content

Commit 8d5f47b

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into net10
2 parents 4211159 + ebdcb3e commit 8d5f47b

File tree

41 files changed

+1046
-793
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1046
-793
lines changed

.github/workflows/build.yml

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
fetch-depth: 0 # needed for Nerdbank.GitVersioning
1616

1717
- name: Setup .NET
18-
uses: actions/setup-dotnet@v4
18+
uses: actions/setup-dotnet@v5
1919

2020
- name: Build Unit Tests .NET
2121
run: dotnet build -f net10.0 test/Renci.SshNet.Tests/
@@ -62,7 +62,7 @@ jobs:
6262
fetch-depth: 0 # needed for Nerdbank.GitVersioning
6363

6464
- name: Setup .NET
65-
uses: actions/setup-dotnet@v4
65+
uses: actions/setup-dotnet@v5
6666

6767
- name: Build Solution
6868
run: dotnet build Renci.SshNet.sln
@@ -103,8 +103,8 @@ jobs:
103103
-p:CoverletOutput=../../coverlet/windows_unit_test_net_4_6_2_coverage.xml `
104104
test/Renci.SshNet.Tests/
105105
106-
Windows-Integration-Tests:
107-
name: Windows Integration Tests
106+
Windows-Integration-Tests-NetFramework:
107+
name: Windows Integration Tests .NET Framework
108108
runs-on: windows-2025
109109
steps:
110110
- name: Checkout
@@ -113,7 +113,7 @@ jobs:
113113
fetch-depth: 0 # needed for Nerdbank.GitVersioning
114114

115115
- name: Setup .NET
116-
uses: actions/setup-dotnet@v4
116+
uses: actions/setup-dotnet@v5
117117

118118
- name: Setup WSL2
119119
uses: Vampire/setup-wsl@6a8db447be7ed35f2f499c02c6e60ff77ef11278 # v6.0.0
@@ -142,7 +142,49 @@ jobs:
142142
- name: Archive Coverlet Results
143143
uses: actions/upload-artifact@v4
144144
with:
145-
name: Coverlet Results Windows
145+
name: Coverlet Results Windows .NET Framework
146+
path: coverlet
147+
148+
Windows-Integration-Tests-Net:
149+
name: Windows Integration Tests .NET
150+
runs-on: windows-2025
151+
steps:
152+
- name: Checkout
153+
uses: actions/checkout@v5
154+
with:
155+
fetch-depth: 0 # needed for Nerdbank.GitVersioning
156+
157+
- name: Setup .NET
158+
uses: actions/setup-dotnet@v5
159+
160+
- name: Setup WSL2
161+
uses: Vampire/setup-wsl@6a8db447be7ed35f2f499c02c6e60ff77ef11278 # v6.0.0
162+
with:
163+
distribution: Ubuntu-24.04
164+
165+
- name: Setup SSH Server
166+
shell: wsl-bash {0}
167+
run: |
168+
apt-get update && apt-get upgrade -y
169+
apt-get install -y podman
170+
podman build -t renci-ssh-tests-server-image -f test/Renci.SshNet.IntegrationTests/Dockerfile test/Renci.SshNet.IntegrationTests/
171+
podman run --rm -h renci-ssh-tests-server -d -p 2222:22 renci-ssh-tests-server-image
172+
173+
- name: Run Integration Tests .NET
174+
run:
175+
dotnet test `
176+
-f net10.0 `
177+
--logger "console;verbosity=normal" `
178+
--logger GitHubActions `
179+
-p:CollectCoverage=true `
180+
-p:CoverletOutputFormat=cobertura `
181+
-p:CoverletOutput=..\..\coverlet\windows_integration_test_net_9_coverage.xml `
182+
test\Renci.SshNet.IntegrationTests\
183+
184+
- name: Archive Coverlet Results
185+
uses: actions/upload-artifact@v4
186+
with:
187+
name: Coverlet Results Windows .NET
146188
path: coverlet
147189

148190
Publish:
@@ -153,6 +195,8 @@ jobs:
153195
needs:
154196
- Windows
155197
- Linux
198+
- Windows-Integration-Tests-NetFramework
199+
- Windows-Integration-Tests-Net
156200
steps:
157201
- name: Download NuGet Package
158202
uses: actions/download-artifact@v5

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
uses: actions/configure-pages@v5
2929

3030
- name: Setup .NET
31-
uses: actions/setup-dotnet@v4
31+
uses: actions/setup-dotnet@v5
3232

3333
- name: Setup docfx
3434
run: dotnet tool update -g docfx

src/Renci.SshNet/Abstractions/SocketAbstraction.cs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,6 @@ namespace Renci.SshNet.Abstractions
1212
{
1313
internal static partial class SocketAbstraction
1414
{
15-
public static bool CanRead(Socket socket)
16-
{
17-
if (socket.Connected)
18-
{
19-
return socket.Poll(-1, SelectMode.SelectRead) && socket.Available > 0;
20-
}
21-
22-
return false;
23-
}
24-
25-
/// <summary>
26-
/// Returns a value indicating whether the specified <see cref="Socket"/> can be used
27-
/// to send data.
28-
/// </summary>
29-
/// <param name="socket">The <see cref="Socket"/> to check.</param>
30-
/// <returns>
31-
/// <see langword="true"/> if <paramref name="socket"/> can be written to; otherwise, <see langword="false"/>.
32-
/// </returns>
33-
public static bool CanWrite(Socket socket)
34-
{
35-
if (socket != null && socket.Connected)
36-
{
37-
return socket.Poll(-1, SelectMode.SelectWrite);
38-
}
39-
40-
return false;
41-
}
42-
4315
public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout)
4416
{
4517
var socket = new Socket(remoteEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { NoDelay = true };

src/Renci.SshNet/Common/Extensions.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using System.Runtime.CompilerServices;
1313
using System.Threading;
1414

15-
using Renci.SshNet.Abstractions;
1615
using Renci.SshNet.Messages;
1716

1817
namespace Renci.SshNet.Common
@@ -321,16 +320,6 @@ public static byte[] Concat(this byte[] first, byte[] second)
321320
return concat;
322321
}
323322

324-
internal static bool CanRead(this Socket socket)
325-
{
326-
return SocketAbstraction.CanRead(socket);
327-
}
328-
329-
internal static bool CanWrite(this Socket socket)
330-
{
331-
return SocketAbstraction.CanWrite(socket);
332-
}
333-
334323
internal static bool IsConnected(this Socket socket)
335324
{
336325
if (socket is null)

src/Renci.SshNet/Security/KeyExchangeEC.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Renci.SshNet.Messages.Transport;
1+
using System;
2+
3+
using Renci.SshNet.Messages.Transport;
24

35
namespace Renci.SshNet.Security
46
{
@@ -76,5 +78,23 @@ public override void Start(Session session, KeyExchangeInitMessage message, bool
7678
_serverPayload = message.GetBytes();
7779
_clientPayload = Session.ClientInitMessage.GetBytes();
7880
}
81+
82+
protected abstract class Impl : IDisposable
83+
{
84+
public abstract byte[] GenerateClientPublicKey();
85+
86+
public abstract byte[] CalculateAgreement(byte[] serverPublicKey);
87+
88+
protected virtual void Dispose(bool disposing)
89+
{
90+
}
91+
92+
public void Dispose()
93+
{
94+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
95+
Dispose(disposing: true);
96+
GC.SuppressFinalize(this);
97+
}
98+
}
7999
}
80100
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#if NET
2+
using System.Security.Cryptography;
3+
4+
namespace Renci.SshNet.Security
5+
{
6+
internal partial class KeyExchangeECCurve25519
7+
{
8+
protected sealed class BclImpl : Impl
9+
{
10+
private readonly ECCurve _curve;
11+
private readonly ECDiffieHellman _clientECDH;
12+
13+
public BclImpl()
14+
{
15+
_curve = ECCurve.CreateFromFriendlyName("Curve25519");
16+
_clientECDH = ECDiffieHellman.Create();
17+
}
18+
19+
public override byte[] GenerateClientPublicKey()
20+
{
21+
_clientECDH.GenerateKey(_curve);
22+
23+
var q = _clientECDH.PublicKey.ExportParameters().Q;
24+
25+
return q.X;
26+
}
27+
28+
public override byte[] CalculateAgreement(byte[] serverPublicKey)
29+
{
30+
var parameters = new ECParameters
31+
{
32+
Curve = _curve,
33+
Q = new ECPoint
34+
{
35+
X = serverPublicKey,
36+
Y = new byte[serverPublicKey.Length]
37+
},
38+
};
39+
40+
using var serverECDH = ECDiffieHellman.Create(parameters);
41+
42+
return _clientECDH.DeriveRawSecretAgreement(serverECDH.PublicKey);
43+
}
44+
45+
protected override void Dispose(bool disposing)
46+
{
47+
base.Dispose(disposing);
48+
49+
if (disposing)
50+
{
51+
_clientECDH.Dispose();
52+
}
53+
}
54+
}
55+
}
56+
}
57+
#endif
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Org.BouncyCastle.Crypto.Agreement;
2+
using Org.BouncyCastle.Crypto.Generators;
3+
using Org.BouncyCastle.Crypto.Parameters;
4+
5+
using Renci.SshNet.Abstractions;
6+
7+
namespace Renci.SshNet.Security
8+
{
9+
internal partial class KeyExchangeECCurve25519
10+
{
11+
protected sealed class BouncyCastleImpl : Impl
12+
{
13+
private X25519Agreement _keyAgreement;
14+
15+
public override byte[] GenerateClientPublicKey()
16+
{
17+
var g = new X25519KeyPairGenerator();
18+
g.Init(new X25519KeyGenerationParameters(CryptoAbstraction.SecureRandom));
19+
20+
var aKeyPair = g.GenerateKeyPair();
21+
_keyAgreement = new X25519Agreement();
22+
_keyAgreement.Init(aKeyPair.Private);
23+
24+
return ((X25519PublicKeyParameters)aKeyPair.Public).GetEncoded();
25+
}
26+
27+
public override byte[] CalculateAgreement(byte[] serverPublicKey)
28+
{
29+
var publicKey = new X25519PublicKeyParameters(serverPublicKey);
30+
31+
var k1 = new byte[_keyAgreement.AgreementSize];
32+
_keyAgreement.CalculateAgreement(publicKey, k1, 0);
33+
34+
return k1;
35+
}
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)