Skip to content

Commit bdaa164

Browse files
RiJoRob-Hague
andauthored
Handle lower-case hex in private key's salt field (#179)
* Handle lower-case hex in private key's salt field I'm using BouncyCastle (http://bouncycastle.org/) to produce public/private key pairs. In later versions of SSH.NET an exception is thrown (SshException: "Invalid private key file.") while establishing connection using the private keys previously generated. It seems to be an issue with the regex matching the private key file data which this commit handles properly. * add test --------- Co-authored-by: Robert Hague <[email protected]>
1 parent 239fe31 commit bdaa164

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/Renci.SshNet/PrivateKeyFile.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ namespace Renci.SshNet
119119
/// </remarks>
120120
public partial class PrivateKeyFile : IPrivateKeySource, IDisposable
121121
{
122-
private const string PrivateKeyPattern = @"^-+ *BEGIN (?<keyName>\w+( \w+)*) *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)(\r?\n)?-+ *END \k<keyName> *-+";
122+
private const string PrivateKeyPattern = @"^-+ *BEGIN (?<keyName>\w+( \w+)*) *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[a-fA-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)(\r?\n)?-+ *END \k<keyName> *-+";
123123
private const string CertificatePattern = @"(?<type>[-\w]+@openssh\.com)\s(?<data>[a-zA-Z0-9\/+=]*)(\s+(?<comment>.*))?";
124124

125125
#if NET7_0_OR_GREATER

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

+48
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Text;
56

67
using Microsoft.VisualStudio.TestTools.UnitTesting;
78

@@ -476,6 +477,52 @@ public void Test_Certificate_OPENSSH_ECDSA()
476477
Assert.AreEqual("ecdsa-sha2-nistp521", algorithms[1].Name);
477478
}
478479

480+
[TestMethod]
481+
public void Test_LowercaseSalt()
482+
{
483+
// Occurs occasionally in keys generated from older BouncyCastle versions
484+
485+
string pk = """
486+
-----BEGIN RSA PRIVATE KEY-----
487+
Proc-Type: 4,ENCRYPTED
488+
DEK-Info: AES-256-CBC,063de67ae11456c89bce9d4a21be3dfb
489+
490+
6mS1GhCjAg5mEwMFcKRJwg1uxCeY3ekJNCQewIN9NSI5A8prBOQ+JSyWAsn6c3Gw
491+
OeRyur+5dxMFdt5Hz1CBi9EePvhVyMry7U5U86BWB0HgtDAD02b324sfc6Wk+kj5
492+
PZvuKyXDiqdwy0rsbBUT+bLtXjCI4Ws1k/KbbF0OqGhFJJvErNU5x8zMD9mqp92R
493+
D8ZZ/F8Sks3V/JeUisAF86sgMfVCELJobn5Zq/IaUyzQwC6IEL+Sy5fSBB5NHiex
494+
NDIJg2RW79uLbufCpuoMPS/GKydf4dq0L5MwvKeqtUgf9Wddc+ZAE4+q1Xz/T8iN
495+
3IMqsQfVbYjVK7uTaVGKH+Ew77Qryj01Vg+zyzdf4UwOV3XXQKLVCjNxpMCVtoq7
496+
S45M3Ad7598vb7ooa/BFCIcEM8TkuzPnuttLqjzXEzUcA5kqm3kV14IKtlexBfNT
497+
tarbidlZcOinvJaoIT3baP4rVnEWDKcxpc+UzNU5RRty6l0zpRmw/9RQ5+FKreh8
498+
eXDHD8TT8ArdaREFM8J2OGpkmIK5sLhhYi9gnTopmKIHn8OAXusmQosEOzS6kGxk
499+
aFtZezXSCBGgXp5RsrBGGx3oXWHGuWbEFXAq+M7PKXMQe5rLRv6sQdfTFSB5hgNK
500+
82P8UzV1wWtAX4JYAhRh2zA8agY2arbNvbjRyjSbp9HNVBgSbVQ60JInesOqLxEg
501+
XURuCYp4F8AeHzyO805MTNpcX7PZT2kOxp9sKKABJ9BJ0RoSWa0LJqXzGCHvrExE
502+
g7XY/ZfDFZlPLbQnrOgVlYh7pzyfyKB74/oXHkonAisRfsgnQ87yT2DmcHNP6Cek
503+
eae2nrpx2yn9Bf8rYdpmJgNxduO8IZvpn84xEyPqK+FbQsdOefBvsg5TgfzETkh/
504+
SJjzbqCTDa3XHEUCInixo/wT7FxT8KR9vk43FGPNVRUvPB2GNxe9ZwLYIir64hcQ
505+
CpdA3ipVx4/jVzWQH8KXG9UP9TDAKXEvbndLnr2taPnUdAnznwHN2EkfzS/PrFG4
506+
/j3l1+VY2AyRybbCTI2iuwJPnKdxOR5oWW6I2Ksfq93Oy+NQz/zasjyNpCZBZWds
507+
5gBmwiNk2Xzq7ikEVtVk3osOQRw/u9GbretfaT9jtClALL3DFbOzL4WxA+0NJqpd
508+
NB2MohOJa1BJjdfh6x6EVhugH85Y9uYyz/MQj7piljAJY96190n3Q86b/7phfwuD
509+
A/ixS42nqpyOPO+EjiWFerFVTJ3iBj7GXXOZGwCrZfpTbqE7OdTDnE3Vr4MO/Etq
510+
kSDmJ/+4SFFh80YwYVERDNFdDxCYxx5AnxaBFwbqjzatTV/btgGVabIf6zm2L6aY
511+
BJ5wnBZnRnsRaIMehDQmTjioMcyHBSMqId+LYQp+KFpBXqXQTEjJPnq+t4o2FF/N
512+
8yoKR8BX6HXSO5qUndI8emwec1JeveiRai6SDnEz1EFfetYXImR290mlqt0aRjQk
513+
t/HXRv+fmDQk5hJbCPICydcVSRyrbzxKkppVceEf9NwkBT1MBsOZIFJ3s3A9I72n
514+
XPIab5czlgSLYA/U9nEg2XU21hKD2kRH1OF0WSlpNhN2SJFViVqlC3v36MgHoWNh
515+
-----END RSA PRIVATE KEY-----
516+
""";
517+
518+
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(pk)))
519+
{
520+
var pkFile = new PrivateKeyFile(stream, "12345");
521+
522+
TestRsaKeyFile(pkFile);
523+
}
524+
}
525+
479526
private void SaveStreamToFile(Stream stream, string fileName)
480527
{
481528
var buffer = new byte[4000];
@@ -500,6 +547,7 @@ private string GetTempFileName()
500547

501548
private static void TestRsaKeyFile(PrivateKeyFile rsaPrivateKeyFile)
502549
{
550+
Assert.IsInstanceOfType<RsaKey>(rsaPrivateKeyFile.Key);
503551
Assert.IsNotNull(rsaPrivateKeyFile.HostKeyAlgorithms);
504552
Assert.AreEqual(3, rsaPrivateKeyFile.HostKeyAlgorithms.Count);
505553

0 commit comments

Comments
 (0)