public void GetSSH2PublicKeyBlobTest() { byte[] actual, expected; PpkFormatter formatter = new PpkFormatter(); ISshKey target; /* test RSA key */ target = formatter.Deserialize(Resources.ssh2_rsa_no_passphrase_ppk); expected = Util.FromBase64( "AAAAB3NzaC1yc2EAAAABJQAAAIEAhWqdEs/lz1r4L8ZAAS76rX7hj3rrI/6FNlBw" + "6ERba2VFmn2AHxQwZmHHmqM+UtiY57angjD9fTbTzL74C0+f/NrRY+BYXf1cF+u5" + "XmjNKygrsIq3yPMZV4q8YcN/ls9COcynOQMIEmJF6Q0LD7Gt9Uv5yjqc2Ay7VVhG" + "qZNnIeE="); actual = target.GetPublicKeyBlob(); Assert.That(expected, Is.EqualTo(actual)); /* test DSA key */ target = formatter.Deserialize(Resources.ssh2_dsa_no_passphrase_ppk); expected = Util.FromBase64( "AAAAB3NzaC1kc3MAAACBAMXDM56ty6fV+qDpMyZxobn5VB4L/E6zvOibUead6HBc" + "OHUibA97EKgooUbqJ9qFUOhhw8TaFtN0UtTLZoHjOWN3JdyugK+f2HYIxvhlvW60" + "8g0lfDU0G4KIXdZukTYm66C0jVSCIdHQ1Iz219JeaEZK00v6wEW7Pp7T7yE71W65" + "AAAAFQDcFrJ83lxI15fUnVl6TSYjB0H7IwAAAIAGatuDAwP1rkYqRH3MbwUTOpzr" + "k/qBYkWbM/8iJlYaWiHjl0rG0HxnwY8Dvb9Knk7Qp6KC8l58KRAiGMrOLBOfPntE" + "gejaXSejM6OARoOtt31IXfOMkbsjAFKFssN+RUDnTPvXPpcL5C3rO1Up4hO3FPqi" + "JQJpL50gTHnDG2Q4BgAAAIA7w6OX/G/pXHDU0M7xXtTN2SOhFQwP8+Tc6h9/Yw/w" + "M9zBXkqb5bdlqy9vRx72/1DXOjH08PIbvza7HfOLkhRri0TYBDJbufQOlK4vQPqF" + "0qhxkYfsgqrZBMBKbLKTZnNm+BW2dgu+QSud67b01IZPzS2i0Z4DgSja9vl3xong" + "Cw=="); actual = target.GetPublicKeyBlob(); Assert.That(expected, Is.EqualTo(actual)); }
public void GetFingerprintTest() { var formatter1 = new Ssh1KeyFormatter(); var rsaSsh1Target = formatter1.Deserialize(Resources.rsa1_1); var rsaSsh1ExpectedFingerprint = Resources.rsa1_1_fp.Trim(); var rsaSsh1Actual = "MD5:" + rsaSsh1Target.GetMD5Fingerprint().ToHexString(); Assert.That(rsaSsh1ExpectedFingerprint, Is.EqualTo(rsaSsh1Actual)); var formatter2 = new PpkFormatter(); var rsaTarget = formatter2.Deserialize(Resources.ssh2_rsa_no_passphrase_ppk); var rsaExpectedFingerprint = "57:95:98:7f:c2:4e:98:1d:b9:5b:45:fe:6d:a4:6b:17"; var rsaActual = rsaTarget.GetMD5Fingerprint().ToHexString(); Assert.That(rsaExpectedFingerprint, Is.EqualTo(rsaActual)); var dsaTarget = formatter2.Deserialize(Resources.ssh2_dsa_no_passphrase_ppk); var dsaExpectedFingerprint = "4e:f1:fc:5d:80:5b:37:b6:13:67:ce:df:4e:83:7b:0b"; var dsaActual = dsaTarget.GetMD5Fingerprint().ToHexString(); Assert.That(dsaExpectedFingerprint, Is.EqualTo(dsaActual)); }
public void PpkFileParseDataTest() { ISshKey target; PpkFormatter.WarnOldFileFormatCallback warnOldFileNotExpected = delegate() { Assert.Fail("Warn old file format was not expected"); }; bool warnCallbackCalled; // set to false before calling warnOldFileExpceted PpkFormatter.WarnOldFileFormatCallback warnOldFileExpected = delegate() { warnCallbackCalled = true; }; string passphrase = "PageantSharp"; PpkFormatter.GetPassphraseCallback getPassphrase = delegate(string comment) { SecureString result = new SecureString(); foreach (char c in passphrase) { result.AppendChar(c); } return(result); }; PpkFormatter.GetPassphraseCallback getBadPassphrase = delegate(string comment) { SecureString result = new SecureString(); foreach (char c in "badword") { result.AppendChar(c); } return(result); }; int expectedKeySize = 1024; // all test keys // string expectedSsh2RsaPublicKeyAlgorithm = PpkFile.PublicKeyAlgorithms.ssh_rsa; // string expectedSsh2RsaWithoutPassPublicKeyString = // "AAAAB3NzaC1yc2EAAAABJQAAAIEAhWqdEs/lz1r4L8ZAAS76rX7hj3rrI/6FNlBw" + // "6ERba2VFmn2AHxQwZmHHmqM+UtiY57angjD9fTbTzL74C0+f/NrRY+BYXf1cF+u5" + // "XmjNKygrsIq3yPMZV4q8YcN/ls9COcynOQMIEmJF6Q0LD7Gt9Uv5yjqc2Ay7VVhG" + // "qZNnIeE="; // string expectedSsh2RsaWithPassPublicKeyString = // "AAAAB3NzaC1yc2EAAAABJQAAAIEAvpwLqhmHYAipvnbQeFEzC7kSTdOCpH5XP9rT" + // "lwScQ5n6Br1DDGIg7tSOBCbralX+0U7NClrcUkueydXRqXEf1rX26o4EcrZ+v1z/" + // "pgu7dbOyHKK0LczCx/IHBm8jrpzrJeB0rg+0ym7XgEcGYgdRj7wFo93PEtx1T4kF" + // "gNLsE3k="; // string expectedSsh2RsaWithoutPassComment = "PageantSharp test: SSH2-RSA, no passphrase"; string expectedSsh2RsaWithPassComment = "PageantSharp test: SSH2-RSA, with passphrase"; // string expectedSsh2RsaWithoutPassPrivateKeyString = // "AAAAgCQO+gUVmA6HSf8S/IqywEqQ/rEoI+A285IjlCMZZNDq8DeXimlDug3VPN2v" + // "lE29/8/sLUXIDSjCtciiUOB2Ypb5Y7AtjDDGg4Yk4v034Mxp0Db6ygDrBuSXbV1U" + // "JzjiDmJOOXgrVLzqc1BZCxVEnzC3fj4GiqQnN1Do3urPatgNAAAAQQDLKWiXIxVj" + // "CoNhzkJqgz0vTIBAaCDJNy9geibZRCHhcQqVk3jN6TscxKhhRYsbEAsTfUPiIPGF" + // "HQaRkd1mwT4dAAAAQQCoHYkHFPqIniQ0oz/ivWAK9mTdl3GRFXP5+mGZQ+9DAl0V" + // "pYOUy7XiCcqVgukYt0+Rj9QNFIcpuAnPfAD6APeVAAAAQClZDkpDCyJX88Vgw7e/" + // "/gbuTJuPv/UGyHI/SSgZcPUBbgmfyj19puHF66+8LTc9unnBF0JyaH9k0dUycFue" + // "LbE="; // string expectedSsh2RsaWithPassDecryptedPrivateKeyString = // "AAAAgE1GLj4KWXn1rJlSwzeyN0nxFUIlUKONKkpRy2a8rg2RczMqIhnG6sGwHeYB" + // "8LxoDVvGABj0ZyhIK53u5kuckF1DiWEcq3IwGIIZqR6JOwMucjbV1pvvzTz3QpUE" + // "fJ+Hj4tHaI7A124D0b/paUmBxOUgeVYXuMls5GZbcl2ApKNdAAAAQQDkXflDxnVr" + // "EXrXAjK+kug3PDdGOPLVPTQRDGwNbuHhSXdVTKAsBdfp9LJZqDzW4LnWhjebeGbj" + // "Kr1ef2VU7cn1AAAAQQDVrHk2uTj27Iwkj31P/WOBXCrmnQ+oAspL3uaJ1rqxg9+F" + // "rq3Dva/y7n0UBRqJ8Y+mdkKQW6oO0usEsEXrVxz1AAAAQF3U8ibnexxDTxhUZdw5" + // "4nzukrnamPWqbZf2RyvQAMA0vw6uW1YNcN6qJxAkt7K5rLg9fsV2ft1FFBcPy+C+" + // "BDw="; string expectedSsh2RsaWithoutPassPrivateMACString = "77bfa6dc141ed17e4c850d3a95cd6f4ec89cd86b"; string oldFileFormatSsh2RsaWithoutPassPrivateMACString = "dc54d9b526e6d5aeb4832811f2b825e735b218f7"; // string expectedSsh2RsaWithPassPrivateMACString = // "e71a6a7b6271875a8264d9d8995f7c81508d6a6c"; string expectedSsh2DsaWithPassComment = "PageantSharp SSH2-DSA, with passphrase"; // string expectedSsh2DsaPrivateKey = "AAAAFQCMF35lBnFwFWyl40y0wTf4lfdhNQ=="; PpkFormatter formatter = new PpkFormatter(); /* test for successful method call */ formatter.GetPassphraseCallbackMethod = getPassphrase; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; var path = Path.Combine(DllDirectory, "../../Resources/ssh2-rsa.ppk"); target = formatter.DeserializeFile(path); Assert.AreEqual(expectedSsh2RsaWithPassComment, target.Comment); Assert.AreEqual(expectedKeySize, target.Size); Assert.That(target.Version, Is.EqualTo(SshVersion.SSH2)); /* read file to string for modification by subsequent tests */ path = Path.Combine(DllDirectory, "../../Resources/ssh2-rsa-no-passphrase.ppk"); byte[] fileData = File.ReadAllBytes(path); string withoutPassFileContents; byte[] modifiedFileContents; MemoryStream modifiedFileContentsStream; withoutPassFileContents = Encoding.UTF8.GetString(fileData); /* test bad file version */ modifiedFileContents = Encoding.UTF8.GetBytes(withoutPassFileContents.Replace("2", "3")); modifiedFileContentsStream = new MemoryStream(modifiedFileContents); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.Fail("Exception did not occur"); } catch (Exception ex) { Assert.IsInstanceOf <PpkFormatterException>(ex); Assert.AreEqual(PpkFormatterException.PpkErrorType.FileVersion, ((PpkFormatterException)ex).PpkError); } /* test bad public key encryption algorithm */ modifiedFileContents = Encoding.UTF8.GetBytes(withoutPassFileContents.Replace("ssh-rsa", "xyz")); modifiedFileContentsStream = new MemoryStream(modifiedFileContents); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.Fail("Exception did not occur"); } catch (Exception ex) { Assert.IsInstanceOf <PpkFormatterException>(ex); Assert.AreEqual(PpkFormatterException.PpkErrorType.PublicKeyEncryption, ((PpkFormatterException)ex).PpkError); } /* test bad private key encryption algorithm */ modifiedFileContents = Encoding.UTF8.GetBytes(withoutPassFileContents.Replace("none", "xyz")); modifiedFileContentsStream = new MemoryStream(modifiedFileContents); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.Fail("Exception did not occur"); } catch (Exception ex) { Assert.IsInstanceOf <PpkFormatterException>(ex); Assert.AreEqual(PpkFormatterException.PpkErrorType.PrivateKeyEncryption, ((PpkFormatterException)ex).PpkError); } /* test bad file integrity */ modifiedFileContents = Encoding.UTF8.GetBytes(withoutPassFileContents.Replace("no passphrase", "xyz")); modifiedFileContentsStream = new MemoryStream(modifiedFileContents); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.Fail("Exception did not occur"); } catch (Exception ex) { Assert.IsInstanceOf <PpkFormatterException>(ex); Assert.AreEqual(PpkFormatterException.PpkErrorType.FileCorrupt, ((PpkFormatterException)ex).PpkError); } /* test bad passphrase */ path = Path.Combine(DllDirectory, "../../Resources/ssh2-rsa.ppk"); fileData = File.ReadAllBytes(path); modifiedFileContentsStream = new MemoryStream(fileData); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.Fail("Exception did not occur"); } catch (Exception ex) { Assert.IsInstanceOf <CallbackNullException>(ex); } path = Path.Combine(DllDirectory, "../../Resources/ssh2-rsa.ppk"); fileData = File.ReadAllBytes(path); modifiedFileContentsStream = new MemoryStream(fileData); formatter.GetPassphraseCallbackMethod = getBadPassphrase; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.Fail("Exception did not occur"); } catch (Exception ex) { Assert.IsInstanceOf <PpkFormatterException>(ex); Assert.AreEqual(PpkFormatterException.PpkErrorType.BadPassphrase, ((PpkFormatterException)ex).PpkError); } /* test old file format */ modifiedFileContents = Encoding.UTF8.GetBytes(withoutPassFileContents .Replace("PuTTY-User-Key-File-2", "PuTTY-User-Key-File-1") .Replace("Private-MAC", "Private-Hash") .Replace(expectedSsh2RsaWithoutPassPrivateMACString, oldFileFormatSsh2RsaWithoutPassPrivateMACString)); modifiedFileContentsStream = new MemoryStream(modifiedFileContents); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileExpected; try { warnCallbackCalled = false; target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.IsTrue(warnCallbackCalled); } catch (Exception ex) { Assert.Fail(ex.ToString()); } /* test reading bad file */ path = Path.Combine(DllDirectory, "../../Resources/emptyFile.ppk"); fileData = File.ReadAllBytes(path); modifiedFileContentsStream = new MemoryStream(fileData); formatter.GetPassphraseCallbackMethod = null; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; try { target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); } catch (Exception ex) { Assert.IsInstanceOf <PpkFormatterException>(ex); Assert.AreEqual(PpkFormatterException.PpkErrorType.FileFormat, ((PpkFormatterException)ex).PpkError); } /* test reading SSH2-DSA files */ path = Path.Combine(DllDirectory, "../../Resources/ssh2-dsa.ppk"); fileData = File.ReadAllBytes(path); modifiedFileContentsStream = new MemoryStream(fileData); formatter.GetPassphraseCallbackMethod = getPassphrase; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; target = (ISshKey)formatter.Deserialize(modifiedFileContentsStream); Assert.AreEqual(expectedSsh2DsaWithPassComment, target.Comment); Assert.AreEqual(expectedKeySize, target.Size); /* test ECDSA and ED25519 keys */ string[] keys = { "../../Resources/ecdsa-sha2-nistp256.ppk", "../../Resources/ecdsa-sha2-nistp256-no-passphrase.ppk", "../../Resources/ecdsa-sha2-nistp384.ppk", "../../Resources/ecdsa-sha2-nistp384-no-passphrase.ppk", "../../Resources/ecdsa-sha2-nistp521.ppk", "../../Resources/ecdsa-sha2-nistp521-no-passphrase.ppk", "../../Resources/ssh2-ed25519.ppk", "../../Resources/ssh2-ed25519-no-passphrase.ppk" }; string[] fps = { "7c:7b:9b:45:ca:dd:d5:d3:9f:25:e7:68:ec:13:7d:79", "80:a9:6e:a1:e4:70:b7:85:ac:e5:df:06:19:95:ce:7d", "13:cc:91:2a:1c:d4:e9:38:cc:df:49:a1:23:fa:38:f2", "e4:c5:a0:c6:b0:b9:fc:9f:0c:7b:6d:98:70:ce:7a:1c", "21:17:40:2e:2a:16:03:f3:ca:79:a2:73:23:f5:ea:d1", "ae:a0:a6:e0:6e:2a:1c:c0:fa:2e:3d:47:15:b3:2b:cb", "5a:b8:a8:f7:1f:06:d6:3b:30:60:a6:41:a0:1f:88:e5", "e4:41:53:cb:04:83:13:b3:58:98:ac:a7:c5:c8:0c:00" }; PublicKeyAlgorithm[] algs = { PublicKeyAlgorithm.ECDSA_SHA2_NISTP256, PublicKeyAlgorithm.ECDSA_SHA2_NISTP256, PublicKeyAlgorithm.ECDSA_SHA2_NISTP384, PublicKeyAlgorithm.ECDSA_SHA2_NISTP384, PublicKeyAlgorithm.ECDSA_SHA2_NISTP521, PublicKeyAlgorithm.ECDSA_SHA2_NISTP521, PublicKeyAlgorithm.ED25519, PublicKeyAlgorithm.ED25519 }; string[] comments = { "PageantSharp ecdsa-sha2-nistp256, with passphrase", "PageantSharp ecdsa-sha2-nistp256, no passphrase", "PageantSharp ecdsa-sha2-nistp384, with passphrase", "PageantSharp ecdsa-sha2-nistp384, no passphrase", "PageantSharp ecdsa-sha2-nistp521, with passphrase", "PageantSharp ecdsa-sha2-nistp521, no passphrase", "PageantSharp ssh2-ed25519, with passphrase", "PageantSharp ssh2-ed25519, no passphrase" }; int[] sizes = { 256, 256, 384, 384, 521, 521, 256, 256 }; formatter.GetPassphraseCallbackMethod = getPassphrase; formatter.WarnOldFileFormatCallbackMethod = warnOldFileNotExpected; for (int i = 0; i < keys.Length; ++i) { path = Path.Combine(DllDirectory, keys[i]); target = (ISshKey)formatter.DeserializeFile(path); Assert.That(target.Size, Is.EqualTo(sizes[i])); Assert.That(target.Algorithm, Is.EqualTo(algs[i])); Assert.That(target.GetMD5Fingerprint().ToHexString(), Is.EqualTo(fps[i])); Assert.That(target.Comment, Is.EqualTo(comments[i])); } }