Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a5bd08d
Assets/logos (#782)
Filini Feb 21, 2021
f072c5f
OPENSSH KeyReader for more keys (#614)
darinkes Apr 18, 2021
583a9ce
Add interface to SftpFile #120 (#812)
wxtsxt Sep 8, 2021
30d79c7
Start MessageListener with ThreadAbstraction.ExecuteThreadLongRunning…
IgorMilavec Nov 28, 2021
7bdfc9e
Add async support to SftpClient and SftpFileStream (#819)
IgorMilavec Dec 14, 2021
cad9433
Add CODEOWNERS file.
drieseng Feb 11, 2022
37fb864
Fix virus false-positive by Defender on Renci.SSHNet.Tests.dll (#867)
zybexXL Feb 14, 2022
4dfc126
Add unit tests for task-based asynchronous API (#906)
IgorMilavec Feb 15, 2022
b30b11a
correct 'Documenation' to 'Documentation' (#838)
maxijabase Feb 15, 2022
bc99ada
Agent auth and Keygen (#794)
darinkes Mar 5, 2022
03c6d60
Use cryptographically secure random number generator.
drieseng May 29, 2022
c728fba
Merge branch 'develop' of https://github.com/sshnet/SSH.NET into develop
drieseng May 29, 2022
bd7c02f
Remove unused import.
drieseng May 29, 2022
34ce2bd
Add IBaseClient for BaseClient and ISftpClient to inherit from (#975)
Owen-Krueger Jul 3, 2022
b9bc475
fix typo (#999)
psh9508 Aug 26, 2022
f3ebc29
Fix Seek Operations in SftpFileStream (#910)
lemonyte Nov 29, 2022
ab2ccc4
Add back copyright to license. (#1060)
drieseng Dec 20, 2022
cf85100
Removing old target frameworks (#1109)
WojciechNagorski May 6, 2023
8c932fb
Remove old features [Part 1] (#1117)
WojciechNagorski May 9, 2023
072ba7e
Remove FEATURE_DIRECTORYINFO_ENUMERATEFILES (#1119)
WojciechNagorski May 22, 2023
3ecbd10
Fix some (lots of) issues reported by analyzers. (#1125)
drieseng May 24, 2023
c04cdbc
Round 2 of analyzer fixes and general cleanup. (#1132)
drieseng May 29, 2023
27976bb
Analyzer fixes round 3. (#1135)
drieseng May 31, 2023
a4dbf77
Replace Array<T>.Empty with Array.Empty<T>() (#1137)
Rob-Hague Jun 6, 2023
4577899
Replace IsNullOrWhiteSpace extension (#1142)
Rob-Hague Jun 12, 2023
a3dbbc5
Use License Expression for NuGet Package
mus65 Jun 25, 2023
69a42d3
Integration tests
WojciechNagorski Jun 29, 2023
6f567ec
Remove todos
WojciechNagorski Jun 29, 2023
3d36f88
Update CODEOWNERS
WojciechNagorski Aug 25, 2023
592c86c
Merge pull request #1146 from mus65/nuget_license
WojciechNagorski Aug 25, 2023
77b27e5
Merge branch 'master' of https://github.com/sshnet/SSH.NET into integ…
WojciechNagorski Aug 26, 2023
82dc77a
Use correct SSH.NET
WojciechNagorski Aug 30, 2023
bfef6aa
Merge branch 'develop' of https://github.com/sshnet/SSH.NET into inte…
WojciechNagorski Aug 30, 2023
1b46264
Merge pull request #1148 from WojciechNagorski/integration-tests-mstests
WojciechNagorski Aug 30, 2023
7cd0487
ListDirectoryAsync return IAsyncEnumerable (#1126)
WojciechNagorski Aug 30, 2023
004b57a
Fix the assembly resolution build warning (#1165)
Rob-Hague Aug 30, 2023
9f1699b
Delete performance/longrunning tests (#1143)
Rob-Hague Sep 6, 2023
9593e87
Move Integration tests (#1173)
WojciechNagorski Sep 12, 2023
60de8a4
Add a benchmarks project (#1151)
Rob-Hague Sep 15, 2023
dcc596a
Use ExceptionDispatchInfo to retain call stack in Session.WaitOnHandl…
IgorMilavec Sep 15, 2023
43329ee
Support SHA256 fingerprints for host key validation (#1098)
DavisNT Sep 17, 2023
8732d3d
Add support for RSA SHA-2 public key algorithms (#1177)
Rob-Hague Sep 23, 2023
18e6673
Improvements after #1177 (#1180)
WojciechNagorski Sep 23, 2023
aade354
Use ExceptionDispatchInfo in more places (#1182)
Rob-Hague Sep 23, 2023
51e0c67
Try to "fix" the flaky test (#1185)
Rob-Hague Sep 25, 2023
fdd1130
Enable DSA tests (#1181)
Rob-Hague Sep 25, 2023
4ba591e
FingerPrints (#1186)
WojciechNagorski Sep 26, 2023
dd2e552
Use OS-agnostic socket error codes to allow tests run on different OS…
dimhotepus Sep 26, 2023
f28c2c2
Fix for channel session semaphore from thread blocking (#1071)
patrick-yates-redgate Sep 28, 2023
cd1151d
Update ISftpClient for #120 (#1193)
WojciechNagorski Sep 29, 2023
5803ada
Implement set last write and access time (#1194)
WojciechNagorski Sep 29, 2023
70f58b7
Add/migrate hmac+cipher integration tests (#1189)
Rob-Hague Sep 29, 2023
1c7166a
Update tests for SetLastAccessTime(Utc) to also verify the time compo…
drieseng Oct 9, 2023
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
Prev Previous commit
Next Next commit
Support SHA256 fingerprints for host key validation (#1098)
* Add tests for HostKeyEventArgs

* Add SHA256 fingerprint support
  • Loading branch information
DavisNT authored Sep 17, 2023
commit 43329eef281fcd364e226dbd6b8c614d97368827
21 changes: 2 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,30 +143,13 @@ using (var client = new SftpClient(connectionInfo))
Establish a SSH connection using user name and password, and reject the connection if the fingerprint of the server does not match the expected fingerprint:

```cs
byte[] expectedFingerPrint = new byte[] {
0x66, 0x31, 0xaf, 0x00, 0x54, 0xb9, 0x87, 0x31,
0xff, 0x58, 0x1c, 0x31, 0xb1, 0xa2, 0x4c, 0x6b
};
string expectedFingerPrint = "LKOy5LvmtEe17S4lyxVXqvs7uPMy+yF79MQpHeCs/Qo";

using (var client = new SshClient("sftp.foo.com", "guest", "pwd"))
{
client.HostKeyReceived += (sender, e) =>
{
if (expectedFingerPrint.Length == e.FingerPrint.Length)
{
for (var i = 0; i < expectedFingerPrint.Length; i++)
{
if (expectedFingerPrint[i] != e.FingerPrint[i])
{
e.CanTrust = false;
break;
}
}
}
else
{
e.CanTrust = false;
}
e.CanTrust = expectedFingerPrint.Equals(e.FingerPrintSHA256);
};
client.Connect();
}
Expand Down
70 changes: 62 additions & 8 deletions src/Renci.SshNet.Tests/Classes/Common/HostKeyEventArgsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using Renci.SshNet.Common;
using Renci.SshNet.Security;
using Renci.SshNet.Tests.Common;
using System.Linq;
using System.Reflection;

namespace Renci.SshNet.Tests.Classes.Common
{
Expand All @@ -10,7 +12,6 @@ namespace Renci.SshNet.Tests.Classes.Common
///to contain all HostKeyEventArgsTest Unit Tests
///</summary>
[TestClass]
[Ignore] // placeholder for actual test
public class HostKeyEventArgsTest : TestBase
{
/// <summary>
Expand All @@ -19,9 +20,52 @@ public class HostKeyEventArgsTest : TestBase
[TestMethod]
public void HostKeyEventArgsConstructorTest()
{
KeyHostAlgorithm host = null; // TODO: Initialize to an appropriate value
HostKeyEventArgs target = new HostKeyEventArgs(host);
Assert.Inconclusive("TODO: Implement code to verify target");
HostKeyEventArgs target = new HostKeyEventArgs(GetKeyHostAlgorithm());
Assert.IsTrue(target.CanTrust);
Assert.IsTrue(new byte[] {
0x00, 0x00, 0x00, 0x07, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x00, 0x00, 0x00, 0x01, 0x23,
0x00, 0x00, 0x01, 0x01, 0x00, 0xb9, 0x3b, 0x57, 0x9f, 0xe0, 0x5a, 0xb5, 0x7d, 0x68, 0x26, 0xeb,
0xe1, 0xa9, 0xf2, 0x59, 0xc3, 0x98, 0xdc, 0xfe, 0x97, 0x08, 0xc4, 0x95, 0x0f, 0x9a, 0xea, 0x05,
0x08, 0x7d, 0xfe, 0x6d, 0x77, 0xca, 0x04, 0x9f, 0xfd, 0xe2, 0x2c, 0x4d, 0x11, 0x3c, 0xd9, 0x05,
0xab, 0x32, 0xbd, 0x3f, 0xe8, 0xcd, 0xba, 0x00, 0x6c, 0x21, 0xb7, 0xa9, 0xc2, 0x4e, 0x63, 0x17,
0xf6, 0x04, 0x47, 0x93, 0x00, 0x85, 0xde, 0xd6, 0x32, 0xc0, 0xa1, 0x37, 0x75, 0x18, 0xa0, 0xb0,
0x32, 0xf6, 0x4e, 0xca, 0x39, 0xec, 0x3c, 0xdf, 0x79, 0xfe, 0x50, 0xa1, 0xc1, 0xf7, 0x67, 0x05,
0xb3, 0x33, 0xa5, 0x96, 0x13, 0x19, 0xfa, 0x14, 0xca, 0x55, 0xe6, 0x7b, 0xf9, 0xb3, 0x8e, 0x32,
0xee, 0xfc, 0x9d, 0x2a, 0x5e, 0x04, 0x79, 0x97, 0x29, 0x3d, 0x1c, 0x54, 0xfe, 0xc7, 0x96, 0x04,
0xb5, 0x19, 0x7c, 0x55, 0x21, 0xe2, 0x0e, 0x42, 0xca, 0x4d, 0x9d, 0xfb, 0x77, 0x08, 0x6c, 0xaa,
0x07, 0x2c, 0xf8, 0xf9, 0x1f, 0xbd, 0x83, 0x14, 0x2b, 0xe0, 0xbc, 0x7a, 0xf9, 0xdf, 0x13, 0x4b,
0x60, 0x5a, 0x02, 0x99, 0x93, 0x41, 0x1a, 0xb6, 0x5f, 0x3b, 0x9c, 0xb5, 0xb2, 0x55, 0x70, 0x78,
0x2f, 0x38, 0x52, 0x0e, 0xd1, 0x8a, 0x2c, 0x23, 0xc0, 0x3a, 0x0a, 0xd7, 0xed, 0xf6, 0x1f, 0xa6,
0x50, 0xf0, 0x27, 0x65, 0x8a, 0xd4, 0xde, 0xa7, 0x1b, 0x41, 0x67, 0xc5, 0x6d, 0x47, 0x84, 0x37,
0x92, 0x2b, 0xb7, 0xb6, 0x4d, 0xb0, 0x1a, 0xda, 0xf6, 0x50, 0x82, 0xf1, 0x57, 0x31, 0x69, 0xce,
0xe0, 0xef, 0xcd, 0x64, 0xaa, 0x78, 0x08, 0xea, 0x4e, 0x45, 0xec, 0xa5, 0x89, 0x68, 0x5d, 0xb4,
0xa0, 0x23, 0xaf, 0xff, 0x9c, 0x0f, 0x8c, 0x83, 0x7c, 0xf8, 0xe1, 0x8e, 0x32, 0x8e, 0x61, 0xfc,
0x5b, 0xbd, 0xd4, 0x46, 0xe1
}.SequenceEqual(target.HostKey));
Assert.AreEqual("ssh-rsa", target.HostKeyName);
Assert.AreEqual(2048, target.KeyLength);
}

/// <summary>
///A test for MD5 calculation in HostKeyEventArgs Constructor
///</summary>
[TestMethod]
public void HostKeyEventArgsConstructorTest_VerifyMD5()
{
HostKeyEventArgs target = new HostKeyEventArgs(GetKeyHostAlgorithm());
Assert.IsTrue(new byte[] {
0x92, 0xea, 0x54, 0xa1, 0x01, 0xf9, 0x95, 0x9c, 0x71, 0xd9, 0xbb, 0x51, 0xb2, 0x55, 0xf8, 0xd9
}.SequenceEqual(target.FingerPrint));
}

/// <summary>
///A test for SHA256 calculation in HostKeyEventArgs Constructor
///</summary>
[TestMethod]
public void HostKeyEventArgsConstructorTest_VerifySHA256()
{
HostKeyEventArgs target = new HostKeyEventArgs(GetKeyHostAlgorithm());
Assert.AreEqual("93LkmoWksp9ytNVZIPXi9KJU1uvlC9clZ/CkUHf6uEE", target.FingerPrintSHA256);
}

/// <summary>
Expand All @@ -30,14 +74,24 @@ public void HostKeyEventArgsConstructorTest()
[TestMethod]
public void CanTrustTest()
{
KeyHostAlgorithm host = null; // TODO: Initialize to an appropriate value
HostKeyEventArgs target = new HostKeyEventArgs(host); // TODO: Initialize to an appropriate value
bool expected = false; // TODO: Initialize to an appropriate value
HostKeyEventArgs target = new HostKeyEventArgs(GetKeyHostAlgorithm());
bool expected = false;
bool actual;
target.CanTrust = expected;
actual = target.CanTrust;
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}

private static KeyHostAlgorithm GetKeyHostAlgorithm()
{
var executingAssembly = Assembly.GetExecutingAssembly();

using (var s = executingAssembly.GetManifestResourceStream(string.Format("Renci.SshNet.Tests.Data.{0}", "Key.RSA.txt")))
{
var privateKey = new PrivateKeyFile(s);
return (KeyHostAlgorithm)privateKey.HostKey;
}
}

}
}
18 changes: 17 additions & 1 deletion src/Renci.SshNet/Common/HostKeyEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,21 @@ public class HostKeyEventArgs : EventArgs
public string HostKeyName{ get; private set; }

/// <summary>
/// Gets the finger print.
/// Gets the MD5 fingerprint.
/// </summary>
/// <value>
/// MD5 fingerprint as byte array.
/// </value>
public byte[] FingerPrint { get; private set; }

/// <summary>
/// Gets the SHA256 fingerprint.
/// </summary>
/// <value>
/// Base64 encoded SHA256 fingerprint with padding (equals sign) removed.
/// </value>
public string FingerPrintSHA256 { get; private set; }

/// <summary>
/// Gets the length of the key in bits.
/// </summary>
Expand All @@ -55,6 +66,11 @@ public HostKeyEventArgs(KeyHostAlgorithm host)
{
FingerPrint = md5.ComputeHash(host.Data);
}

using (var sha256 = CryptoAbstraction.CreateSHA256())
{
FingerPrintSHA256 = Convert.ToBase64String(sha256.ComputeHash(host.Data)).Replace("=", "");
}
}
}
}