Skip to content

Commit

Permalink
Add Tests for PuTTY-Format
Browse files Browse the repository at this point in the history
  • Loading branch information
darinkes committed Mar 19, 2024
1 parent bc09fdd commit 3d90170
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
77 changes: 50 additions & 27 deletions SshNet.Keygen.Tests/TestKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public void TestExceptions()

keyInfo.KeyType = SshKeyType.RSA;
Assert.Throws<CryptographicException>(() => SshKey.Generate(keyInfo));

var key = SshKey.Generate();
Assert.Throws<NotSupportedException>(() => key.ToPuttyFormat(SshKeyFormat.OpenSSH));
}

[Test]
Expand All @@ -41,7 +44,7 @@ public void TestDefaultKey()
private static void KeyGenTest<TKey>(SshKeyType keyType, int keyLength = 0)
{
const string password = "12345";
var comments = new[] { "", "Generated by SshNet.Keygen"};
var comments = new[] { null, "", "Generated by SshNet.Keygen"};

var sshKeyEncryptions = new List<ISshKeyEncryption>()
{
Expand All @@ -57,24 +60,14 @@ private static void KeyGenTest<TKey>(SshKeyType keyType, int keyLength = 0)
{
foreach (var sshKeyEncryption in sshKeyEncryptions)
{
TestContext.WriteLine($"File: {path} - Encryption: {sshKeyEncryption}");
TestContext.WriteLine($"File: '{path}' - Encryption: '{sshKeyEncryption}' - Comment: '{comment}'");

var keyInfo = new SshKeyGenerateInfo(keyType)
{
Encryption = sshKeyEncryption,
KeyLength = keyLength
};
if (!string.IsNullOrEmpty(comment))
keyInfo.Comment = comment;

var puttyKeyInfo = new SshKeyGenerateInfo(keyType)
{
KeyFormat = SshKeyFormat.PuTTYv3,
Encryption = sshKeyEncryption,
KeyLength = keyLength
KeyLength = keyLength,
Comment = comment
};
if (!string.IsNullOrEmpty(comment))
puttyKeyInfo.Comment = comment;

IPrivateKeySource keyFile;
if (string.IsNullOrEmpty(path))
Expand All @@ -89,27 +82,57 @@ private static void KeyGenTest<TKey>(SshKeyType keyType, int keyLength = 0)
keyFile = new PrivateKeyFile(path, password);
ClassicAssert.IsTrue(File.Exists(path));

switch (sshKeyEncryption.CipherName)
foreach (var keyFormat in new List<SshKeyFormat> { SshKeyFormat.PuTTYv2 , SshKeyFormat.PuTTYv3 })
{
case "aes256-ctr":
Assert.Throws<NotSupportedException>(() => SshKey.Generate($"{path}.ppk", FileMode.Create, puttyKeyInfo));
break;
default:
File.Delete($"{path}.ppk");
_ = SshKey.Generate($"{path}.ppk", FileMode.Create, puttyKeyInfo);
ClassicAssert.IsTrue(File.Exists($"{path}.ppk"));
break;
keyInfo.KeyFormat = keyFormat;
var puttyFile = $"{path}-{keyFormat}.ppk";

switch (sshKeyEncryption.CipherName)
{
case "aes256-ctr":
Assert.Throws<NotSupportedException>(() => SshKey.Generate(puttyFile, FileMode.Create, keyInfo));
break;
default:
File.Delete(puttyFile);
_ = SshKey.Generate(puttyFile, FileMode.Create, keyInfo);
ClassicAssert.IsTrue(File.Exists(puttyFile));

var puttyContent = File.ReadAllText(puttyFile);

StringAssert.Contains(
comment is null
? $"Comment: {SshKeyGenerateInfo.DefaultSshKeyComment}"
: $"Comment: {comment}", puttyContent);

StringAssert.Contains($"Encryption: {sshKeyEncryption.CipherName}", puttyContent);

switch (keyFormat)
{
case SshKeyFormat.PuTTYv2:
StringAssert.Contains("PuTTY-User-Key-File-2: ", puttyContent);
break;
case SshKeyFormat.PuTTYv3:
StringAssert.Contains("PuTTY-User-Key-File-3: ", puttyContent);
if (keyInfo.Encryption is SshKeyEncryptionAes256)
{
StringAssert.Contains("Key-Derivation: Argon2id", puttyContent);
StringAssert.Contains("Argon2-Memory: 8192", puttyContent);
StringAssert.Contains("Argon2-Passes: 22", puttyContent);
StringAssert.Contains("Argon2-Parallelism: 1", puttyContent);
StringAssert.Contains("Argon2-Salt:", puttyContent);
}
break;
}
break;
}
}
}

ClassicAssert.IsInstanceOf<TKey>(((KeyHostAlgorithm) keyFile.HostKeyAlgorithms.First()).Key);
if (keyLength != 0)
ClassicAssert.AreEqual(keyLength, (((KeyHostAlgorithm) keyFile.HostKeyAlgorithms.First()).Key.KeyLength));

ClassicAssert.AreEqual(
string.IsNullOrEmpty(comment)
? $"{Environment.UserName}@{Environment.MachineName}"
: comment,
ClassicAssert.AreEqual(comment ?? SshKeyGenerateInfo.DefaultSshKeyComment,
((KeyHostAlgorithm) keyFile.HostKeyAlgorithms.First()).Key.Comment);
}
}
Expand Down
2 changes: 1 addition & 1 deletion SshNet.Keygen/SshKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public static GeneratedPrivateKey Generate(SshKeyGenerateInfo info)
throw new NotSupportedException($"Unsupported KeyType: {info.KeyType}");
}

key.Comment = info.Comment;
key.Comment = info.Comment ?? SshKeyGenerateInfo.DefaultSshKeyComment;
return new GeneratedPrivateKey(key, info);
}

Expand Down
2 changes: 1 addition & 1 deletion SshNet.Keygen/SshKeyGenerateInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class SshKeyGenerateInfo

public ISshKeyEncryption Encryption { get; set; }

public string Comment { get; set; }
public string? Comment { get; set; }

public SshKeyFormat KeyFormat { get; set; }

Expand Down

0 comments on commit 3d90170

Please sign in to comment.