Skip to content

Commit 90fb62b

Browse files
committed
Add Support for ECDSA Host- and Private-Keys
Also known as: - ecdsa-sha2-nistp256 - ecdsa-sha2-nistp384 - ecdsa-sha2-nistp521 Basically it translate between SSH-Data and Microsoft Crypto API.
1 parent b58a11c commit 90fb62b

19 files changed

+981
-22
lines changed

src/Renci.SshNet.NET35/Renci.SshNet.NET35.csproj

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<DebugType>full</DebugType>
1919
<Optimize>false</Optimize>
2020
<OutputPath>bin\Debug\</OutputPath>
21-
<DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
21+
<DefineConstants>TRACE;DEBUG;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_ECDSA</DefineConstants>
2222
<ErrorReport>prompt</ErrorReport>
2323
<WarningLevel>4</WarningLevel>
2424
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -29,7 +29,7 @@
2929
<DebugType>none</DebugType>
3030
<Optimize>true</Optimize>
3131
<OutputPath>bin\Release\</OutputPath>
32-
<DefineConstants>TRACE;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII</DefineConstants>
32+
<DefineConstants>TRACE;FEATURE_REGEX_COMPILE;FEATURE_BINARY_SERIALIZATION;FEATURE_RNG_CREATE;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_ENCODING_ASCII;FEATURE_ECDSA</DefineConstants>
3333
<ErrorReport>prompt</ErrorReport>
3434
<WarningLevel>4</WarningLevel>
3535
<DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
@@ -911,6 +911,12 @@
911911
<Compile Include="..\Renci.SshNet\Security\Cryptography\Key.cs">
912912
<Link>Security\Cryptography\Key.cs</Link>
913913
</Compile>
914+
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaDigitalSignature.cs">
915+
<Link>Security\Cryptography\EcdsaDigitalSignature.cs</Link>
916+
</Compile>
917+
<Compile Include="..\Renci.SshNet\Security\Cryptography\EcdsaKey.cs">
918+
<Link>Security\Cryptography\EcdsaKey.cs</Link>
919+
</Compile>
914920
<Compile Include="..\Renci.SshNet\Security\Cryptography\RsaDigitalSignature.cs">
915921
<Link>Security\Cryptography\RsaDigitalSignature.cs</Link>
916922
</Compile>

src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
</ItemGroup>
2828
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
2929
<PackageReference Include="SshNet.Security.Cryptography" Version="[1.3.0]" />
30+
<PackageReference Include="System.Security.Cryptography.Cng" Version="4.4.0" />
3031
</ItemGroup>
3132
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
3233
<DefineConstants>FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_DNS_TAP;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512</DefineConstants>
3334
</PropertyGroup>
3435
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
35-
<DefineConstants>FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP;FEATURE_STREAM_APM;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512</DefineConstants>
36+
<DefineConstants>FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_SOCKET_DISPOSE;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP;FEATURE_STREAM_APM;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_TAP;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_WAITHANDLE_DISPOSE;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_ECDSA</DefineConstants>
3637
</PropertyGroup>
3738
</Project>

src/Renci.SshNet.Tests.NET35/Renci.SshNet.Tests.NET35.csproj

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@
354354
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_ToBigInteger2.cs">
355355
<Link>Classes\Common\ExtensionsTest_ToBigInteger2.cs</Link>
356356
</Compile>
357+
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_Pad.cs">
358+
<Link>Classes\Common\ExtensionsTest_Pad.cs</Link>
359+
</Compile>
357360
<Compile Include="..\Renci.SshNet.Tests\Classes\Common\ExtensionsTest_TrimLeadingZeros.cs">
358361
<Link>Classes\Common\ExtensionsTest_TrimLeadingZeros.cs</Link>
359362
</Compile>
@@ -1740,6 +1743,26 @@
17401743
<Link>Data\Key.SSH2.RSA.txt</Link>
17411744
</EmbeddedResource>
17421745
</ItemGroup>
1746+
<ItemGroup>
1747+
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA.txt">
1748+
<Link>Data\Key.ECDSA.txt</Link>
1749+
</EmbeddedResource>
1750+
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA384.txt">
1751+
<Link>Data\Key.ECDSA384.txt</Link>
1752+
</EmbeddedResource>
1753+
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA521.txt">
1754+
<Link>Data\Key.ECDSA521.txt</Link>
1755+
</EmbeddedResource>
1756+
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA.Encrypted.txt">
1757+
<Link>Data\Key.ECDSA.Encrypted.txt</Link>
1758+
</EmbeddedResource>
1759+
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA384.Encrypted.txt">
1760+
<Link>Data\Key.ECDSA384.Encrypted.txt</Link>
1761+
</EmbeddedResource>
1762+
<EmbeddedResource Include="..\Renci.SshNet.Tests\Data\Key.ECDSA521.Encrypted.txt">
1763+
<Link>Data\Key.ECDSA521.Encrypted.txt</Link>
1764+
</EmbeddedResource>
1765+
</ItemGroup>
17431766
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
17441767
<ProjectExtensions>
17451768
<VisualStudio>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Renci.SshNet.Common;
5+
6+
namespace Renci.SshNet.Tests.Classes.Common
7+
{
8+
[TestClass]
9+
[SuppressMessage("ReSharper", "InvokeAsExtensionMethod")]
10+
public class ExtensionsTest_Pad
11+
{
12+
[TestMethod]
13+
public void ShouldReturnNotPadded()
14+
{
15+
byte[] value = {0x0a, 0x0d};
16+
byte[] padded = value.Pad(2);
17+
Assert.AreEqual(value, padded);
18+
Assert.AreEqual(value.Length, padded.Length);
19+
}
20+
21+
[TestMethod]
22+
public void ShouldReturnPadded()
23+
{
24+
byte[] value = { 0x0a, 0x0d };
25+
byte[] padded = value.Pad(3);
26+
Assert.AreEqual(value.Length + 1, padded.Length);
27+
Assert.AreEqual(0x00, padded[0]);
28+
Assert.AreEqual(0x0a, padded[1]);
29+
Assert.AreEqual(0x0d, padded[2]);
30+
}
31+
}
32+
}

src/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,72 @@ public void Test_PrivateKey_RSA_DES_EDE3_CFB()
319319
}
320320
}
321321

322+
[TestMethod]
323+
[Owner("darinkes")]
324+
[TestCategory("PrivateKey")]
325+
public void Test_PrivateKey_ECDSA()
326+
{
327+
using (var stream = GetData("Key.ECDSA.txt"))
328+
{
329+
new PrivateKeyFile(stream);
330+
}
331+
}
332+
333+
[TestMethod]
334+
[Owner("darinkes")]
335+
[TestCategory("PrivateKey")]
336+
public void Test_PrivateKey_ECDSA384()
337+
{
338+
using (var stream = GetData("Key.ECDSA384.txt"))
339+
{
340+
new PrivateKeyFile(stream);
341+
}
342+
}
343+
344+
[TestMethod]
345+
[Owner("darinkes")]
346+
[TestCategory("PrivateKey")]
347+
public void Test_PrivateKey_ECDSA521()
348+
{
349+
using (var stream = GetData("Key.ECDSA521.txt"))
350+
{
351+
new PrivateKeyFile(stream);
352+
}
353+
}
354+
355+
[TestMethod]
356+
[Owner("darinkes")]
357+
[TestCategory("PrivateKey")]
358+
public void Test_PrivateKey_ECDSA_Encrypted()
359+
{
360+
using (var stream = GetData("Key.ECDSA.Encrypted.txt"))
361+
{
362+
new PrivateKeyFile(stream, "12345");
363+
}
364+
}
365+
366+
[TestMethod]
367+
[Owner("darinkes")]
368+
[TestCategory("PrivateKey")]
369+
public void Test_PrivateKey_ECDSA384_Encrypted()
370+
{
371+
using (var stream = GetData("Key.ECDSA384.Encrypted.txt"))
372+
{
373+
new PrivateKeyFile(stream, "12345");
374+
}
375+
}
376+
377+
[TestMethod]
378+
[Owner("darinkes")]
379+
[TestCategory("PrivateKey")]
380+
public void Test_PrivateKey_ECDSA521_Encrypted()
381+
{
382+
using (var stream = GetData("Key.ECDSA521.Encrypted.txt"))
383+
{
384+
new PrivateKeyFile(stream, "12345");
385+
}
386+
}
387+
322388
/// <summary>
323389
///A test for Dispose
324390
///</summary>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
Proc-Type: 4,ENCRYPTED
3+
DEK-Info: AES-128-CBC,54D46F498C989115AAE14FEA21E3AF11
4+
5+
IQdFnndcbzz10d7YQIgEE1TzuzJrm7uYJr4Hvdfz/FshVxMRqxqaqtEgo2vAHHik
6+
BOcPkm+84ERlTNPslcJqLSkKzCdxb7Rz5hfwHuN3Y6Lf01qGakDlzAUEjEyDor+4
7+
zQtAne+f+gRUJnBvLLoVhH4xdeQFC55GECNUFQpEmos=
8+
-----END EC PRIVATE KEY-----
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
MHcCAQEEIEdqaFKgJBIibVjyUh1v7Y35LwIQJrocdTaYFLwl7iB0oAoGCCqGSM49
3+
AwEHoUQDQgAEQD5MO/n9yqSDTszwzVpApLx5SQFecE5ZfDkgxqVdHQecm1BAPozZ
4+
4eKGNhKn72hT79mLlp9HXX+oNEcuVT83Hw==
5+
-----END EC PRIVATE KEY-----
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
Proc-Type: 4,ENCRYPTED
3+
DEK-Info: AES-128-CBC,1D64653C5E18C2AACB0B17E3FE43C219
4+
5+
lCtRmcvKSeIACwqTtsf/ei1brtCZ386rsk/j7bSXdkZBpvzcmzbeo6w6CYm206Km
6+
hV9TMl2dIO/I1/ov5/2VIR3ZkaElyDOJD/+Be0e3aus4EZj1H1YM/Dv+4QJId+is
7+
Cw4ycWjfudYPPejGdiyjzt5qjaIJwrrEvGtMg7sWVAqDpjcAjS9KuaCu5nOgdItL
8+
s7oHuz+DTGdJQNfUHAlUnz1JaMRWzpP0MwtxdcaRY+w=
9+
-----END EC PRIVATE KEY-----
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
MIGkAgEBBDCQawHdHLR7NvKa2vPV0sVkbzOE8c0enp95iEysGcGV66RXE1EH//nh
3+
gu5UzeTR4KigBwYFK4EEACKhZANiAAQUk4rVvoOPI1hQzWpNx09Uo6qG+srGcbvB
4+
q15eFK0GnK/T0UBKxdbZ2+//KAYI6SeDHM9t3ORF1aX5EpjTEBI4d7ZY/lV9jX6M
5+
nJ4XuGteJselM2iMmy+p9ZYw83BYB1Y=
6+
-----END EC PRIVATE KEY-----
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
Proc-Type: 4,ENCRYPTED
3+
DEK-Info: AES-128-CBC,F995028237EBD79C928530CC6C3E957F
4+
5+
wT+iajbte4MnpCipVy/7W9t2I8OgwbMjNBw9PB5xmXR1NQX+yWa81DXMTgjHi8++
6+
6tp+Vlftkr7mY1yvZCVo1Sy4VgcvZeMhtpVKtvYdMCmHJC6gaDOTYX3yee8DJ4FL
7+
fG+IQz0wFyZZ26NFrHiwbufW9z6pXhGNCQZK0KLbFxI9iKwVA0llc7uzTEcmBBpn
8+
0/Snp0CVvX+i6AP9Xj0bBdrFCsvcoT+ZHzS8YWJUfu3m6cpAJksCAy0PXR3ifvus
9+
edTfDpkMxd4/b+DtPB6SMekIAjnQyzbyaTwJCujm8iU=
10+
-----END EC PRIVATE KEY-----

0 commit comments

Comments
 (0)