diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index 414bcfcd7..495d079d1 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -119,7 +119,7 @@ namespace Renci.SshNet /// public partial class PrivateKeyFile : IPrivateKeySource, IDisposable { - private const string PrivateKeyPattern = @"^-+ *BEGIN (?\w+( \w+)*) *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?[A-Z0-9-]+),(?[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?([a-zA-Z0-9/+=]{1,80}\r?\n)+)(\r?\n)?-+ *END \k *-+"; + private const string PrivateKeyPattern = @"^-+ *BEGIN (?\w+( \w+)*) *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?[A-Z0-9-]+),(?[a-fA-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?([a-zA-Z0-9/+=]{1,80}\r?\n)+)(\r?\n)?-+ *END \k *-+"; private const string CertificatePattern = @"(?[-\w]+@openssh\.com)\s(?[a-zA-Z0-9\/+=]*)(\s+(?.*))?"; #if NET7_0_OR_GREATER diff --git a/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs b/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs index 32dba2cb0..1e5b5f7f9 100644 --- a/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs +++ b/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -476,6 +477,52 @@ public void Test_Certificate_OPENSSH_ECDSA() Assert.AreEqual("ecdsa-sha2-nistp521", algorithms[1].Name); } + [TestMethod] + public void Test_LowercaseSalt() + { + // Occurs occasionally in keys generated from older BouncyCastle versions + + string pk = """ + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-256-CBC,063de67ae11456c89bce9d4a21be3dfb + + 6mS1GhCjAg5mEwMFcKRJwg1uxCeY3ekJNCQewIN9NSI5A8prBOQ+JSyWAsn6c3Gw + OeRyur+5dxMFdt5Hz1CBi9EePvhVyMry7U5U86BWB0HgtDAD02b324sfc6Wk+kj5 + PZvuKyXDiqdwy0rsbBUT+bLtXjCI4Ws1k/KbbF0OqGhFJJvErNU5x8zMD9mqp92R + D8ZZ/F8Sks3V/JeUisAF86sgMfVCELJobn5Zq/IaUyzQwC6IEL+Sy5fSBB5NHiex + NDIJg2RW79uLbufCpuoMPS/GKydf4dq0L5MwvKeqtUgf9Wddc+ZAE4+q1Xz/T8iN + 3IMqsQfVbYjVK7uTaVGKH+Ew77Qryj01Vg+zyzdf4UwOV3XXQKLVCjNxpMCVtoq7 + S45M3Ad7598vb7ooa/BFCIcEM8TkuzPnuttLqjzXEzUcA5kqm3kV14IKtlexBfNT + tarbidlZcOinvJaoIT3baP4rVnEWDKcxpc+UzNU5RRty6l0zpRmw/9RQ5+FKreh8 + eXDHD8TT8ArdaREFM8J2OGpkmIK5sLhhYi9gnTopmKIHn8OAXusmQosEOzS6kGxk + aFtZezXSCBGgXp5RsrBGGx3oXWHGuWbEFXAq+M7PKXMQe5rLRv6sQdfTFSB5hgNK + 82P8UzV1wWtAX4JYAhRh2zA8agY2arbNvbjRyjSbp9HNVBgSbVQ60JInesOqLxEg + XURuCYp4F8AeHzyO805MTNpcX7PZT2kOxp9sKKABJ9BJ0RoSWa0LJqXzGCHvrExE + g7XY/ZfDFZlPLbQnrOgVlYh7pzyfyKB74/oXHkonAisRfsgnQ87yT2DmcHNP6Cek + eae2nrpx2yn9Bf8rYdpmJgNxduO8IZvpn84xEyPqK+FbQsdOefBvsg5TgfzETkh/ + SJjzbqCTDa3XHEUCInixo/wT7FxT8KR9vk43FGPNVRUvPB2GNxe9ZwLYIir64hcQ + CpdA3ipVx4/jVzWQH8KXG9UP9TDAKXEvbndLnr2taPnUdAnznwHN2EkfzS/PrFG4 + /j3l1+VY2AyRybbCTI2iuwJPnKdxOR5oWW6I2Ksfq93Oy+NQz/zasjyNpCZBZWds + 5gBmwiNk2Xzq7ikEVtVk3osOQRw/u9GbretfaT9jtClALL3DFbOzL4WxA+0NJqpd + NB2MohOJa1BJjdfh6x6EVhugH85Y9uYyz/MQj7piljAJY96190n3Q86b/7phfwuD + A/ixS42nqpyOPO+EjiWFerFVTJ3iBj7GXXOZGwCrZfpTbqE7OdTDnE3Vr4MO/Etq + kSDmJ/+4SFFh80YwYVERDNFdDxCYxx5AnxaBFwbqjzatTV/btgGVabIf6zm2L6aY + BJ5wnBZnRnsRaIMehDQmTjioMcyHBSMqId+LYQp+KFpBXqXQTEjJPnq+t4o2FF/N + 8yoKR8BX6HXSO5qUndI8emwec1JeveiRai6SDnEz1EFfetYXImR290mlqt0aRjQk + t/HXRv+fmDQk5hJbCPICydcVSRyrbzxKkppVceEf9NwkBT1MBsOZIFJ3s3A9I72n + XPIab5czlgSLYA/U9nEg2XU21hKD2kRH1OF0WSlpNhN2SJFViVqlC3v36MgHoWNh + -----END RSA PRIVATE KEY----- + """; + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(pk))) + { + var pkFile = new PrivateKeyFile(stream, "12345"); + + TestRsaKeyFile(pkFile); + } + } + private void SaveStreamToFile(Stream stream, string fileName) { var buffer = new byte[4000]; @@ -500,6 +547,7 @@ private string GetTempFileName() private static void TestRsaKeyFile(PrivateKeyFile rsaPrivateKeyFile) { + Assert.IsInstanceOfType(rsaPrivateKeyFile.Key); Assert.IsNotNull(rsaPrivateKeyFile.HostKeyAlgorithms); Assert.AreEqual(3, rsaPrivateKeyFile.HostKeyAlgorithms.Count);