From d89c44e09d2c852d125ea6f8e66956b9fc1be405 Mon Sep 17 00:00:00 2001 From: Rob Hague Date: Sun, 22 Dec 2024 15:45:59 +0000 Subject: [PATCH] Drop DSA DSA is removed at compile time from OpenSSH 9.8 and higher. That means we can no longer test it in our integration tests. It seems like a good time to remove it. From the OpenSSH release notes: DSA, as specified in the SSHv2 protocol, is inherently weak - being limited to a 160 bit private key and use of the SHA1 digest. Its estimated security level is only 80 bits symmetric equivalent. OpenSSH has disabled DSA keys by default since 2015 but has retained run-time optional support for them. DSA was the only mandatory-to- implement algorithm in the SSHv2 RFCs, mostly because alternative algorithms were encumbered by patents when the SSHv2 protocol was specified. This has not been the case for decades at this point and better algorithms are well supported by all actively-maintained SSH implementations. We do not consider the costs of maintaining DSA in OpenSSH to be justified and hope that removing it from OpenSSH can accelerate its wider deprecation in supporting cryptography libraries. --- src/Renci.SshNet/ConnectionInfo.cs | 1 - src/Renci.SshNet/PrivateKeyFile.PKCS1.cs | 2 - src/Renci.SshNet/PrivateKeyFile.PKCS8.cs | 21 -- src/Renci.SshNet/PrivateKeyFile.PuTTY.cs | 12 +- src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs | 15 -- src/Renci.SshNet/PrivateKeyFile.cs | 4 - src/Renci.SshNet/Security/Certificate.cs | 3 - .../Cryptography/DsaDigitalSignature.cs | 86 ------- .../Security/Cryptography/DsaKey.cs | 220 ------------------ ....DSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt | 12 - test/Data/Key.DSA.PKCS8.txt | 9 - test/Data/Key.DSA.pub | 1 - test/Data/Key.DSA.txt | 12 - ...ey.PuTTY3.DSA.Encrypted.Argon2id.12345.ppk | 22 -- test/Data/Key.PuTTY3.DSA.ppk | 17 -- .../Key.SSH2.DSA.Encrypted.Des.CBC.12345.pub | 1 - .../Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt | 12 - test/Data/Key.SSH2.DSA.pub | 1 - test/Data/Key.SSH2.DSA.txt | 13 -- .../HostKeyAlgorithmTests.cs | 6 - .../PrivateKeyAuthenticationTests.cs | 6 - .../Classes/PrivateKeyFileTest.cs | 7 - .../Classes/ScpClientTest.cs | 8 +- .../Cryptography/DsaDigitalSignatureTest.cs | 59 ----- .../Security/Cryptography/DsaKeyTest.cs | 205 ---------------- 25 files changed, 6 insertions(+), 749 deletions(-) delete mode 100644 src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs delete mode 100644 src/Renci.SshNet/Security/Cryptography/DsaKey.cs delete mode 100644 test/Data/Key.DSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt delete mode 100644 test/Data/Key.DSA.PKCS8.txt delete mode 100644 test/Data/Key.DSA.pub delete mode 100644 test/Data/Key.DSA.txt delete mode 100644 test/Data/Key.PuTTY3.DSA.Encrypted.Argon2id.12345.ppk delete mode 100644 test/Data/Key.PuTTY3.DSA.ppk delete mode 100644 test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.pub delete mode 100644 test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt delete mode 100644 test/Data/Key.SSH2.DSA.pub delete mode 100644 test/Data/Key.SSH2.DSA.txt delete mode 100644 test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaDigitalSignatureTest.cs delete mode 100644 test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaKeyTest.cs diff --git a/src/Renci.SshNet/ConnectionInfo.cs b/src/Renci.SshNet/ConnectionInfo.cs index 52f614554..473d7fb26 100644 --- a/src/Renci.SshNet/ConnectionInfo.cs +++ b/src/Renci.SshNet/ConnectionInfo.cs @@ -404,7 +404,6 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy hostAlgs.Add("rsa-sha2-512", data => { var key = new RsaKey(new SshKeyData(data)); return new KeyHostAlgorithm("rsa-sha2-512", key, new RsaDigitalSignature(key, HashAlgorithmName.SHA512)); }); hostAlgs.Add("rsa-sha2-256", data => { var key = new RsaKey(new SshKeyData(data)); return new KeyHostAlgorithm("rsa-sha2-256", key, new RsaDigitalSignature(key, HashAlgorithmName.SHA256)); }); hostAlgs.Add("ssh-rsa", data => new KeyHostAlgorithm("ssh-rsa", new RsaKey(new SshKeyData(data)))); - hostAlgs.Add("ssh-dss", data => new KeyHostAlgorithm("ssh-dss", new DsaKey(new SshKeyData(data)))); #pragma warning restore SA1107 // Code should not contain multiple statements on one line HostKeyAlgorithms = hostAlgs; diff --git a/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs b/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs index f0dc68ec6..64b3af553 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs @@ -83,8 +83,6 @@ public Key Parse() { case "RSA PRIVATE KEY": return new RsaKey(decryptedData); - case "DSA PRIVATE KEY": - return new DsaKey(decryptedData); case "EC PRIVATE KEY": return new EcdsaKey(decryptedData); default: diff --git a/src/Renci.SshNet/PrivateKeyFile.PKCS8.cs b/src/Renci.SshNet/PrivateKeyFile.PKCS8.cs index ad4586155..45ba357d3 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PKCS8.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PKCS8.cs @@ -54,27 +54,6 @@ public Key Parse() return new RsaKey(key); } - if (algorithmOid.Equals(X9ObjectIdentifiers.IdDsa)) - { - var parameters = privateKeyInfo.PrivateKeyAlgorithm.Parameters.GetDerEncoded(); - var parametersReader = new AsnReader(parameters, AsnEncodingRules.BER); - var sequenceReader = parametersReader.ReadSequence(); - parametersReader.ThrowIfNotEmpty(); - - var p = sequenceReader.ReadInteger(); - var q = sequenceReader.ReadInteger(); - var g = sequenceReader.ReadInteger(); - sequenceReader.ThrowIfNotEmpty(); - - var keyReader = new AsnReader(key, AsnEncodingRules.BER); - var x = keyReader.ReadInteger(); - keyReader.ThrowIfNotEmpty(); - - var y = BigInteger.ModPow(g, x, p); - - return new DsaKey(p, q, g, y, x); - } - if (algorithmOid.Equals(X9ObjectIdentifiers.IdECPublicKey)) { var parameters = privateKeyInfo.PrivateKeyAlgorithm.Parameters.GetDerEncoded(); diff --git a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs index 627fcb991..6b1f0ea82 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs @@ -184,20 +184,12 @@ public Key Parse() var prv = privateKeyReader.ReadBignum2(); parsedKey = new EcdsaKey(curve, pub, prv); break; - case "ssh-dss": - var p = publicKeyReader.ReadBignum(); - var q = publicKeyReader.ReadBignum(); - var g = publicKeyReader.ReadBignum(); - var y = publicKeyReader.ReadBignum(); - var x = privateKeyReader.ReadBignum(); - parsedKey = new DsaKey(p, q, g, y, x); - break; case "ssh-rsa": var exponent = publicKeyReader.ReadBignum(); // e var modulus = publicKeyReader.ReadBignum(); // n var d = privateKeyReader.ReadBignum(); // d - p = privateKeyReader.ReadBignum(); // p - q = privateKeyReader.ReadBignum(); // q + var p = privateKeyReader.ReadBignum(); // p + var q = privateKeyReader.ReadBignum(); // q var inverseQ = privateKeyReader.ReadBignum(); // iqmp parsedKey = new RsaKey(modulus, exponent, d, p, q, inverseQ); break; diff --git a/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs b/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs index 290494c4b..25df02595 100644 --- a/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs +++ b/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs @@ -82,21 +82,6 @@ public Key Parse() var p = reader.ReadBigIntWithBits(); // q return new RsaKey(modulus, exponent, d, p, q, inverseQ); } - else if (keyType.Contains("dsa")) - { - var zero = reader.ReadUInt32(); - if (zero != 0) - { - throw new SshException("Invalid private key"); - } - - var p = reader.ReadBigIntWithBits(); - var g = reader.ReadBigIntWithBits(); - var q = reader.ReadBigIntWithBits(); - var y = reader.ReadBigIntWithBits(); - var x = reader.ReadBigIntWithBits(); - return new DsaKey(p, q, g, y, x); - } throw new NotSupportedException(string.Format("Key type '{0}' is not supported.", keyType)); } diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index b9dbdf5e1..47fae404c 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -384,10 +384,6 @@ private void Open(Stream privateKey, string? passPhrase) _hostAlgorithms.Add(new KeyHostAlgorithm("rsa-sha2-256", _key, new RsaDigitalSignature(rsaKey, HashAlgorithmName.SHA256))); #pragma warning restore CA2000 // Dispose objects before losing scope } - else if (_key is DsaKey) - { - _hostAlgorithms.Add(new KeyHostAlgorithm("ssh-dss", _key)); - } else { _hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key)); diff --git a/src/Renci.SshNet/Security/Certificate.cs b/src/Renci.SshNet/Security/Certificate.cs index 788239c4c..30f083c1a 100644 --- a/src/Renci.SshNet/Security/Certificate.cs +++ b/src/Renci.SshNet/Security/Certificate.cs @@ -348,9 +348,6 @@ private Key ReadPublicKey(out SshKeyData keyData) case "ssh-rsa-cert-v01@openssh.com": keyData = new SshKeyData("ssh-rsa", LoadPublicKeys(2)); return new RsaKey(keyData); - case "ssh-dss-cert-v01@openssh.com": - keyData = new SshKeyData("ssh-dss", LoadPublicKeys(4)); - return new DsaKey(keyData); case "ecdsa-sha2-nistp256-cert-v01@openssh.com": case "ecdsa-sha2-nistp384-cert-v01@openssh.com": case "ecdsa-sha2-nistp521-cert-v01@openssh.com": diff --git a/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs b/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs deleted file mode 100644 index b779d418a..000000000 --- a/src/Renci.SshNet/Security/Cryptography/DsaDigitalSignature.cs +++ /dev/null @@ -1,86 +0,0 @@ -#nullable enable -using System; -using System.Security.Cryptography; - -using Renci.SshNet.Common; - -namespace Renci.SshNet.Security.Cryptography -{ - /// - /// Implements DSA digital signature algorithm. - /// - public class DsaDigitalSignature : DigitalSignature, IDisposable - { - private readonly DsaKey _key; - - /// - /// Initializes a new instance of the class. - /// - /// The DSA key. - /// is . - public DsaDigitalSignature(DsaKey key) - { - ThrowHelper.ThrowIfNull(key); - - _key = key; - } - - /// - public override bool Verify(byte[] input, byte[] signature) - { -#if NETSTANDARD2_1_OR_GREATER || NET - return _key.DSA.VerifyData(input, signature, HashAlgorithmName.SHA1); -#else - // VerifyData does not exist on netstandard2.0. - // It does exist on net462, but in order to keep the path tested, - // use it on netfx as well. - using (var sha1 = SHA1.Create()) - { - var hash = sha1.ComputeHash(input); - return _key.DSA.VerifySignature(hash, signature); - } -#endif - } - - /// - /// Creates the signature. - /// - /// The input. - /// - /// Signed input data. - /// - /// Invalid DSA key. - public override byte[] Sign(byte[] input) - { -#if NETSTANDARD2_1_OR_GREATER || NET - return _key.DSA.SignData(input, HashAlgorithmName.SHA1); -#else - // SignData does not exist on netstandard2.0. - // It does exist on net462, but in order to keep the path tested, - // use it on netfx as well. - using (var sha1 = SHA1.Create()) - { - var hash = sha1.ComputeHash(input); - return _key.DSA.CreateSignature(hash); - } -#endif - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// to release both managed and unmanaged resources; to release only unmanaged resources. - protected virtual void Dispose(bool disposing) - { - } - } -} diff --git a/src/Renci.SshNet/Security/Cryptography/DsaKey.cs b/src/Renci.SshNet/Security/Cryptography/DsaKey.cs deleted file mode 100644 index 5335f20ba..000000000 --- a/src/Renci.SshNet/Security/Cryptography/DsaKey.cs +++ /dev/null @@ -1,220 +0,0 @@ -#nullable enable -using System; -using System.Formats.Asn1; -using System.Numerics; -using System.Security.Cryptography; - -using Renci.SshNet.Common; -using Renci.SshNet.Security.Cryptography; - -namespace Renci.SshNet.Security -{ - /// - /// Contains DSA private and public key. - /// - public class DsaKey : Key, IDisposable - { - private DsaDigitalSignature? _digitalSignature; - - internal DSA DSA { get; } - - /// - /// Gets the P. - /// - public BigInteger P { get; } - - /// - /// Gets the Q. - /// - public BigInteger Q { get; } - - /// - /// Gets the G. - /// - public BigInteger G { get; } - - /// - /// Gets public key Y. - /// - public BigInteger Y { get; } - - /// - /// Gets private key X. - /// - public BigInteger X { get; } - - /// - public override int KeyLength - { - get - { - return (int)P.GetBitLength(); - } - } - - /// - /// Gets the digital signature. - /// - protected internal override DigitalSignature DigitalSignature - { - get - { - _digitalSignature ??= new DsaDigitalSignature(this); - return _digitalSignature; - } - } - - /// - /// Gets the DSA public key. - /// - /// - /// An array whose values are: - /// - /// 0 - /// 1 - /// 2 - /// 3 - /// - /// - public override BigInteger[] Public - { - get - { - return new[] { P, Q, G, Y }; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The encoded public key data. - public DsaKey(SshKeyData publicKeyData) - { - ThrowHelper.ThrowIfNull(publicKeyData); - - if (publicKeyData.Name != "ssh-dss" || publicKeyData.Keys.Length != 4) - { - throw new ArgumentException($"Invalid DSA public key data. ({publicKeyData.Name}, {publicKeyData.Keys.Length}).", nameof(publicKeyData)); - } - - P = publicKeyData.Keys[0]; - Q = publicKeyData.Keys[1]; - G = publicKeyData.Keys[2]; - Y = publicKeyData.Keys[3]; - - DSA = LoadDSA(); - } - - /// - /// Initializes a new instance of the class. - /// - /// DER encoded private key data. - public DsaKey(byte[] privateKeyData) - { - ThrowHelper.ThrowIfNull(privateKeyData); - - var keyReader = new AsnReader(privateKeyData, AsnEncodingRules.DER); - var sequenceReader = keyReader.ReadSequence(); - keyReader.ThrowIfNotEmpty(); - - _ = sequenceReader.ReadInteger(); // skip version - - P = sequenceReader.ReadInteger(); - Q = sequenceReader.ReadInteger(); - G = sequenceReader.ReadInteger(); - Y = sequenceReader.ReadInteger(); - X = sequenceReader.ReadInteger(); - - sequenceReader.ThrowIfNotEmpty(); - - DSA = LoadDSA(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The p. - /// The q. - /// The g. - /// The y. - /// The x. - public DsaKey(BigInteger p, BigInteger q, BigInteger g, BigInteger y, BigInteger x) - { - P = p; - Q = q; - G = g; - Y = y; - X = x; - - DSA = LoadDSA(); - } - -#pragma warning disable CA1859 // Use concrete types when possible for improved performance -#pragma warning disable CA5384 // Do Not Use Digital Signature Algorithm (DSA) - private DSA LoadDSA() - { -#if NETFRAMEWORK - // On .NET Framework we use the concrete CNG type which is FIPS-186-3 - // compatible. The CryptoServiceProvider type returned by DSA.Create() - // is limited to FIPS-186-1 (max 1024 bit key). - var dsa = new DSACng(); -#else - var dsa = DSA.Create(); -#endif - dsa.ImportParameters(GetDSAParameters()); - - return dsa; - } -#pragma warning restore CA5384 // Do Not Use Digital Signature Algorithm (DSA) -#pragma warning restore CA1859 // Use concrete types when possible for improved performance - - internal DSAParameters GetDSAParameters() - { - // P, G, Y, Q are required. - // P, G, Y must have the same length. - // If X is present, it must have the same length as Q. - - // See https://github.com/dotnet/runtime/blob/fadd8313653f71abd0068c8bf914be88edb2c8d3/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs#L23 - // and https://github.com/dotnet/runtime/blob/fadd8313653f71abd0068c8bf914be88edb2c8d3/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs#L18 - // (and similar code in RsaKey.cs) - - var ret = new DSAParameters - { - P = P.ToByteArray(isUnsigned: true, isBigEndian: true), - Q = Q.ToByteArray(isUnsigned: true, isBigEndian: true), - }; - - ret.G = G.ExportKeyParameter(ret.P.Length); - ret.Y = Y.ExportKeyParameter(ret.P.Length); - - if (!X.IsZero) - { - ret.X = X.ExportKeyParameter(ret.Q.Length); - } - - return ret; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// to release both managed and unmanaged resources; to release only unmanaged resources. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _digitalSignature?.Dispose(); - DSA.Dispose(); - } - } - } -} diff --git a/test/Data/Key.DSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt b/test/Data/Key.DSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt deleted file mode 100644 index 03773bbfb..000000000 --- a/test/Data/Key.DSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIBrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIjn9BgD9X0loCAggA -MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBB3Zthr23nQDulzKryFEUTFBIIB -UDW8/IR0K5DRScH4Cl7HOoK20aR+TmUOGczE027RL++iosgk5rYUpIKn0pxIKM0U -StFGTqLz3G+bEh/Bm2Vt03Qv0Q2QZoX2e1Vktt32X2cLBNzGWfEpLuCD4vG8QDRW -uGkE1NHxJKQTJWQt/gwGituyhMThGoE3ZcuqeLmRlhUSgRccO6WJ2HkNOW7TM5RB -QbeBXmYB1H5S3FjpRAvd2p9dEzDsyquQaltFM4kekIxGjwiw5WSd+KsCGXFLa2Y2 -OXvcjRIIqGBJr+xvEVA86TNTfad+sKGqGUFszRmnGXA+VxEZju2OCpVhxTLEMX4Q -2vYz9i8jE78tpx7C6PTKoJe5FTdlTatvWvYD5cvcbazPUjuZbraI9ha4XvNtERGC -J0voz/7yeuNkW1ofxTUOu+snGhySC4AXkC44eZG4wUPfuQAswP8dFiQi2BthgVyP -kA== ------END ENCRYPTED PRIVATE KEY----- diff --git a/test/Data/Key.DSA.PKCS8.txt b/test/Data/Key.DSA.PKCS8.txt deleted file mode 100644 index f5baf96e5..000000000 --- a/test/Data/Key.DSA.PKCS8.txt +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBALVl3fae2O4qwsAK95SUShX0KMUN -P+yl/uT3lGH9T/ZptnHSlrTxnTWXCl0g91KEeCaEnDDhLxm4aCv1Ag4B/yvcM4u3 -4qkmaNLy2LiAxiqdobZcNG61Pqwqd5IDkp38LBsn8tmb12xu9NalpUfOiSEB1cyC -r4zFZMrm0wtdyJQVAhUArvojZKn/2DgGI2Kx0ghxZlgHxGECgYAOVJ434UAR3Hn6 -lA5nWNfFOuUVH3W7nJaP0FQJiIPx7GUbdxO9qtDNTbWkWL3c9qx5+B7Ole4xM7cv -yXPrNQUYDHCFlS+Ue2x3IeJrkdfZkH9ePP25y5A0J4/c+8XXvQaj4zA5nfw13oy5 -Ptyd7d3Kq5tEDM8KiVdIhwkXjUA3PQQWAhQYRjs5PgIpnqG/euBPPh7EDZcnXg== ------END PRIVATE KEY----- diff --git a/test/Data/Key.DSA.pub b/test/Data/Key.DSA.pub deleted file mode 100644 index f32c6fae0..000000000 --- a/test/Data/Key.DSA.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBALVl3fae2O4qwsAK95SUShX0KMUNP+yl/uT3lGH9T/ZptnHSlrTxnTWXCl0g91KEeCaEnDDhLxm4aCv1Ag4B/yvcM4u34qkmaNLy2LiAxiqdobZcNG61Pqwqd5IDkp38LBsn8tmb12xu9NalpUfOiSEB1cyCr4zFZMrm0wtdyJQVAAAAFQCu+iNkqf/YOAYjYrHSCHFmWAfEYQAAAIAOVJ434UAR3Hn6lA5nWNfFOuUVH3W7nJaP0FQJiIPx7GUbdxO9qtDNTbWkWL3c9qx5+B7Ole4xM7cvyXPrNQUYDHCFlS+Ue2x3IeJrkdfZkH9ePP25y5A0J4/c+8XXvQaj4zA5nfw13oy5Ptyd7d3Kq5tEDM8KiVdIhwkXjUA3PQAAAIEAm8IGZQatS7M6AfNITNWG4TI7Z2aRQjLb9/MWJIID7c/VQ4zdTZdG3kpk0Gj9n4xreopK5NmYAdj8rtFfPBgmXltsLqt+bBcXkpxW//7WC29WOXW3t90ySTh+cWuWfr9fV7mf4Ql/6u/ZIgpQNvnNYezazt3fK8EXjI1dAXEuQxE= diff --git a/test/Data/Key.DSA.txt b/test/Data/Key.DSA.txt deleted file mode 100644 index 6c84e0c65..000000000 --- a/test/Data/Key.DSA.txt +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQC1Zd32ntjuKsLACveUlEoV9CjFDT/spf7k95Rh/U/2abZx0pa0 -8Z01lwpdIPdShHgmhJww4S8ZuGgr9QIOAf8r3DOLt+KpJmjS8ti4gMYqnaG2XDRu -tT6sKneSA5Kd/CwbJ/LZm9dsbvTWpaVHzokhAdXMgq+MxWTK5tMLXciUFQIVAK76 -I2Sp/9g4BiNisdIIcWZYB8RhAoGADlSeN+FAEdx5+pQOZ1jXxTrlFR91u5yWj9BU -CYiD8exlG3cTvarQzU21pFi93PasefgezpXuMTO3L8lz6zUFGAxwhZUvlHtsdyHi -a5HX2ZB/Xjz9ucuQNCeP3PvF170Go+MwOZ38Nd6MuT7cne3dyqubRAzPColXSIcJ -F41ANz0CgYEAm8IGZQatS7M6AfNITNWG4TI7Z2aRQjLb9/MWJIID7c/VQ4zdTZdG -3kpk0Gj9n4xreopK5NmYAdj8rtFfPBgmXltsLqt+bBcXkpxW//7WC29WOXW3t90y -STh+cWuWfr9fV7mf4Ql/6u/ZIgpQNvnNYezazt3fK8EXjI1dAXEuQxECFBhGOzk+ -Aimeob964E8+HsQNlyde ------END DSA PRIVATE KEY----- diff --git a/test/Data/Key.PuTTY3.DSA.Encrypted.Argon2id.12345.ppk b/test/Data/Key.PuTTY3.DSA.Encrypted.Argon2id.12345.ppk deleted file mode 100644 index a6205ded4..000000000 --- a/test/Data/Key.PuTTY3.DSA.Encrypted.Argon2id.12345.ppk +++ /dev/null @@ -1,22 +0,0 @@ -PuTTY-User-Key-File-3: ssh-dss -Encryption: aes256-cbc -Comment: imported-openssh-key -Public-Lines: 10 -AAAAB3NzaC1kc3MAAACBALVl3fae2O4qwsAK95SUShX0KMUNP+yl/uT3lGH9T/Zp -tnHSlrTxnTWXCl0g91KEeCaEnDDhLxm4aCv1Ag4B/yvcM4u34qkmaNLy2LiAxiqd -obZcNG61Pqwqd5IDkp38LBsn8tmb12xu9NalpUfOiSEB1cyCr4zFZMrm0wtdyJQV -AAAAFQCu+iNkqf/YOAYjYrHSCHFmWAfEYQAAAIAOVJ434UAR3Hn6lA5nWNfFOuUV -H3W7nJaP0FQJiIPx7GUbdxO9qtDNTbWkWL3c9qx5+B7Ole4xM7cvyXPrNQUYDHCF -lS+Ue2x3IeJrkdfZkH9ePP25y5A0J4/c+8XXvQaj4zA5nfw13oy5Ptyd7d3Kq5tE -DM8KiVdIhwkXjUA3PQAAAIEAm8IGZQatS7M6AfNITNWG4TI7Z2aRQjLb9/MWJIID -7c/VQ4zdTZdG3kpk0Gj9n4xreopK5NmYAdj8rtFfPBgmXltsLqt+bBcXkpxW//7W -C29WOXW3t90ySTh+cWuWfr9fV7mf4Ql/6u/ZIgpQNvnNYezazt3fK8EXjI1dAXEu -QxE= -Key-Derivation: Argon2id -Argon2-Memory: 8192 -Argon2-Passes: 8 -Argon2-Parallelism: 1 -Argon2-Salt: 310d916da49faba22ba8d2745777e5c5 -Private-Lines: 1 -xMm0Tg+o7Yq6lAs6L33y2fy3fiDPl6p71iKxm8OAgj4= -Private-MAC: fc2aef48bf90b80b97d06c32c37491db614331c2551ab37865d8719ee6cb5f4f diff --git a/test/Data/Key.PuTTY3.DSA.ppk b/test/Data/Key.PuTTY3.DSA.ppk deleted file mode 100644 index abecad674..000000000 --- a/test/Data/Key.PuTTY3.DSA.ppk +++ /dev/null @@ -1,17 +0,0 @@ -PuTTY-User-Key-File-3: ssh-dss -Encryption: none -Comment: imported-openssh-key -Public-Lines: 10 -AAAAB3NzaC1kc3MAAACBALVl3fae2O4qwsAK95SUShX0KMUNP+yl/uT3lGH9T/Zp -tnHSlrTxnTWXCl0g91KEeCaEnDDhLxm4aCv1Ag4B/yvcM4u34qkmaNLy2LiAxiqd -obZcNG61Pqwqd5IDkp38LBsn8tmb12xu9NalpUfOiSEB1cyCr4zFZMrm0wtdyJQV -AAAAFQCu+iNkqf/YOAYjYrHSCHFmWAfEYQAAAIAOVJ434UAR3Hn6lA5nWNfFOuUV -H3W7nJaP0FQJiIPx7GUbdxO9qtDNTbWkWL3c9qx5+B7Ole4xM7cvyXPrNQUYDHCF -lS+Ue2x3IeJrkdfZkH9ePP25y5A0J4/c+8XXvQaj4zA5nfw13oy5Ptyd7d3Kq5tE -DM8KiVdIhwkXjUA3PQAAAIEAm8IGZQatS7M6AfNITNWG4TI7Z2aRQjLb9/MWJIID -7c/VQ4zdTZdG3kpk0Gj9n4xreopK5NmYAdj8rtFfPBgmXltsLqt+bBcXkpxW//7W -C29WOXW3t90ySTh+cWuWfr9fV7mf4Ql/6u/ZIgpQNvnNYezazt3fK8EXjI1dAXEu -QxE= -Private-Lines: 1 -AAAAFBhGOzk+Aimeob964E8+HsQNlyde -Private-MAC: 6c517ac5ede72c006b0115dd9d0830c8e699a1f4d72c708d41f68b6263d974ae diff --git a/test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.pub b/test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.pub deleted file mode 100644 index 3b07844b3..000000000 --- a/test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAI8gyHFchkVhkPiwkhkjFDqN6w2nFWTqVy9sLjFs38oEWLMpAw9+c132erUptAhNQ6JZUAVZGllv/3V5hksSDyChe9WY5IfsOlh6X0dcZCwBKysEzQlPyMFqAtbc9uv7oUWNzBfvEbtV6WN/VmcmXf7dyo3EBVXbBFdPl1NKC7W9AAAAFQDY1+bTt7s2iNmYoBE4C9hdWRCyeQAAAIAEtj09ugx/Tdl6bo7X6mX17hcgVgIxcYj5VNONg2k6IHmRFriLviYaS68mIB4SG3jmvvxbXAGqR1bWBUrv90n0wpxxcuuNoCFylJQyuqUkzSsUHb0WMcncZ/tBQt+NJnRB1Zp9sw8n20ocpg3WVPdaXTtc4pk83NYB6ywG6UFPvgAAAIAX+De5dwo33LMl9W8IvA4dY8Q1wshdycAGJzhy+qYF9dCcwD1Pg+4EbPjYPmzJopsVrK97v9QhxyYcXMr/iHhngGwd9nYNzzSKx665vkSjzyeJWpeQ+fvNV3CLItP01ypbUreM+s+Vz1wor5joLKcDS4X0oQ0RIVZNEHnekuLuFg== diff --git a/test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt b/test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt deleted file mode 100644 index e7d775846..000000000 --- a/test/Data/Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt +++ /dev/null @@ -1,12 +0,0 @@ ----- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- -P2/56wAAAgoAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA -AIM2Rlcy1jYmMAAAHIxrKV3QJkISlRHox4JYLlWJG0ccdEfMmDF3IXW+up6nUQZeWyOS9/ -csXyclUtJ/adA0qkpH5hcaIIOr1jQgvPxjMy7o3I5WJ/MvKB7omSDYG82wKZAaZQeSCaqY -Cn1DYHz6Xou5BIle37f0y71tq3d7YFCh33BjbCM8KHsar3TgRf3oegaawZyZuLnnZRy0L+ -xdsdqgntc4fyhpmCmfwIYhWwD2R9P56FXTw59VuE0r/LxxLJW8Cq2R8i7bN0lb2ezb3qnU -SykSJ5PYvoW6e7HIZ3GEr9d+wDhqp0SKWHl+shed3e5xi1NF7fRR23bZ1xlAk3FdrBrH1b -aWYW4JFzdVc33Pg5oHLe+q5NQ3vQpMxXlN2IG9cdAigWKNJMdvLuxiYi+6lzNIGAH+yb01 -56ksXYgUs65Gqnj0GMYVmf//8NN0gRKXl5dT57LyuU42jRePwANMyO/n9QOi9OKeea8Tku -f6ZMRiHQLDiZx2ShEXEhHRwmv42jt2xjuHNMbY0dZTKZEkFMUGVFVbkl5MEmN8Fj59rHJn -0adWRPLH5smwM8WXbaYt+E0r628UNZbedXCcjZ5c5egpxCBxRrSJqnK1f0l899fulB ----- END SSH2 ENCRYPTED PRIVATE KEY ---- diff --git a/test/Data/Key.SSH2.DSA.pub b/test/Data/Key.SSH2.DSA.pub deleted file mode 100644 index 654400140..000000000 --- a/test/Data/Key.SSH2.DSA.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAOCSGuOxxY/DQBowG7fkS30AJmwN4fDPXToyTaAaxwpOWnGJXFhgP4Il+GSKlpaxnUWkajKpMc1b1hhawPWN4sxoT8QRb6SAW30ErnT/pUtsxqoFlkFla4xvWSgNAuHAVkUBrgPsJ4sHehSbNFn3I6q8Rgle2jyHDHTOqPj2KEXhAAAAFQC740YkVJdVpTJRTxd9Myi0Nx3t4wAAAIArvP7AGh5jY+zxeQRb52zxcUamRBkVYL/ferdJNi9hoM8ZaO4++Xgs8wMbpmoEch9DsXdtufjqXWpk7ywlPjcdhhsb3MxJAeEeFtTRsu2/IUTKqKPHIOgoiPzs8q69AxWhV10aDDUdYWLkqPV/tMGl6S/jC7vTJLmhZum4BUv8MQAAAIEAt19oHPIPyv/8mbMaYpu8I6kvj1/97Ejw0neN7Cd9cGZLqIPBwTyUHEQvKSAm4BvNP0Le3JDn3RFayhRmf+8RrAmS4d1MjrCOs6fmeyLnk2kTpRPFZ2x0H1udIRAhzRehyfj6OsAHn7Jclr+mqDhoq7nIfC3tSgWxFH5g948+7ks= imported-openssh-key diff --git a/test/Data/Key.SSH2.DSA.txt b/test/Data/Key.SSH2.DSA.txt deleted file mode 100644 index a4dc6d077..000000000 --- a/test/Data/Key.SSH2.DSA.txt +++ /dev/null @@ -1,13 +0,0 @@ ----- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- -Comment: "imported-openssh-key" -P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA -AEbm9uZQAAAcQAAAHAAAAAAAAABADgkhrjscWPw0AaMBu35Et9ACZsDeHwz106Mk2gGscK -TlpxiVxYYD+CJfhkipaWsZ1FpGoyqTHNW9YYWsD1jeLMaE/EEW+kgFt9BK50/6VLbMaqBZ -ZBZWuMb1koDQLhwFZFAa4D7CeLB3oUmzRZ9yOqvEYJXto8hwx0zqj49ihF4QAAA/4rvP7A -Gh5jY+zxeQRb52zxcUamRBkVYL/ferdJNi9hoM8ZaO4++Xgs8wMbpmoEch9DsXdtufjqXW -pk7ywlPjcdhhsb3MxJAeEeFtTRsu2/IUTKqKPHIOgoiPzs8q69AxWhV10aDDUdYWLkqPV/ -tMGl6S/jC7vTJLmhZum4BUv8MQAAAKC740YkVJdVpTJRTxd9Myi0Nx3t4wAABAC3X2gc8g -/K//yZsxpim7wjqS+PX/3sSPDSd43sJ31wZkuog8HBPJQcRC8pICbgG80/Qt7ckOfdEVrK -FGZ/7xGsCZLh3UyOsI6zp+Z7IueTaROlE8VnbHQfW50hECHNF6HJ+Po6wAefslyWv6aoOG -iruch8Le1KBbEUfmD3jz7uSwAAAJ9mUEtdk3zSMZJ1umUnNSo5zC+UxA== ----- END SSH2 ENCRYPTED PRIVATE KEY ---- diff --git a/test/Renci.SshNet.IntegrationTests/HostKeyAlgorithmTests.cs b/test/Renci.SshNet.IntegrationTests/HostKeyAlgorithmTests.cs index 40049938f..d37230abc 100644 --- a/test/Renci.SshNet.IntegrationTests/HostKeyAlgorithmTests.cs +++ b/test/Renci.SshNet.IntegrationTests/HostKeyAlgorithmTests.cs @@ -24,12 +24,6 @@ public void TearDown() _remoteSshdConfig?.Reset(); } - [TestMethod] - public void SshDss() - { - DoTest(HostKeyAlgorithm.SshDss, HostKeyFile.Dsa); - } - [TestMethod] public void SshRsa() { diff --git a/test/Renci.SshNet.IntegrationTests/PrivateKeyAuthenticationTests.cs b/test/Renci.SshNet.IntegrationTests/PrivateKeyAuthenticationTests.cs index 6a4a37cdc..2fa7fc25f 100644 --- a/test/Renci.SshNet.IntegrationTests/PrivateKeyAuthenticationTests.cs +++ b/test/Renci.SshNet.IntegrationTests/PrivateKeyAuthenticationTests.cs @@ -22,12 +22,6 @@ public void TearDown() _remoteSshdConfig?.Reset(); } - [TestMethod] - public void SshDss() - { - DoTest(PublicKeyAlgorithm.SshDss, "Data.Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt", "12345"); - } - [TestMethod] public void SshRsa() { diff --git a/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs b/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs index d28ba0a06..8090ec42c 100644 --- a/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs +++ b/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs @@ -311,9 +311,6 @@ public void ConstructorWithFileNameAndPassPhraseShouldBeAbleToReadFileThatIsShar } [TestMethod] - [DataRow("Key.DSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt", "12345", typeof(DsaKey))] - [DataRow("Key.DSA.PKCS8.txt", null, typeof(DsaKey))] - [DataRow("Key.DSA.txt", null, typeof(DsaKey))] [DataRow("Key.ECDSA.Encrypted.txt", "12345", typeof(EcdsaKey))] [DataRow("Key.ECDSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt", "12345", typeof(EcdsaKey))] [DataRow("Key.ECDSA.PKCS8.txt", null, typeof(EcdsaKey))] @@ -348,8 +345,6 @@ public void ConstructorWithFileNameAndPassPhraseShouldBeAbleToReadFileThatIsShar [DataRow("Key.PuTTY2.Ed25519.ppk", null, typeof(ED25519Key))] [DataRow("Key.PuTTY2.RSA.Encrypted.12345.ppk", "12345", typeof(RsaKey))] [DataRow("Key.PuTTY2.RSA.ppk", null, typeof(RsaKey))] - [DataRow("Key.PuTTY3.DSA.Encrypted.Argon2id.12345.ppk", "12345", typeof(DsaKey))] - [DataRow("Key.PuTTY3.DSA.ppk", null, typeof(DsaKey))] [DataRow("Key.PuTTY3.ECDSA.Encrypted.Argon2id.12345.ppk", "12345", typeof(EcdsaKey))] [DataRow("Key.PuTTY3.ECDSA.ppk", null, typeof(EcdsaKey))] [DataRow("Key.PuTTY3.Ed25519.Encrypted.Argon2i.12345.ppk", "12345", typeof(ED25519Key))] @@ -367,8 +362,6 @@ public void ConstructorWithFileNameAndPassPhraseShouldBeAbleToReadFileThatIsShar [DataRow("Key.RSA.PKCS8.Encrypted.Aes.256.CBC.12345.txt", "12345", typeof(RsaKey))] [DataRow("Key.RSA.PKCS8.txt", null, typeof(RsaKey))] [DataRow("Key.RSA.txt", null, typeof(RsaKey))] - [DataRow("Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt", "12345", typeof(DsaKey))] - [DataRow("Key.SSH2.DSA.txt", null, typeof(DsaKey))] [DataRow("Key.SSH2.RSA.Encrypted.Des.CBC.12345.txt", "12345", typeof(RsaKey))] [DataRow("Key.SSH2.RSA.txt", null, typeof(RsaKey))] public void Test_PrivateKey(string name, string passPhrase, Type expectedKeyType) diff --git a/test/Renci.SshNet.Tests/Classes/ScpClientTest.cs b/test/Renci.SshNet.Tests/Classes/ScpClientTest.cs index d44afb78c..89be6801e 100644 --- a/test/Renci.SshNet.Tests/Classes/ScpClientTest.cs +++ b/test/Renci.SshNet.Tests/Classes/ScpClientTest.cs @@ -121,7 +121,7 @@ public void Ctor_HostAndPortAndUsernameAndPrivateKeys() var host = _random.Next().ToString(); var port = _random.Next(1, 100); var userName = _random.Next().ToString(); - var privateKeys = new[] { GetRsaKey(), GetDsaKey() }; + var privateKeys = new[] { GetRsaKey(), GetEcdsaKey() }; var client = new ScpClient(host, port, userName, privateKeys); Assert.AreEqual(16 * 1024U, client.BufferSize); @@ -154,7 +154,7 @@ public void Ctor_HostAndUsernameAndPrivateKeys() { var host = _random.Next().ToString(); var userName = _random.Next().ToString(); - var privateKeys = new[] { GetRsaKey(), GetDsaKey() }; + var privateKeys = new[] { GetRsaKey(), GetEcdsaKey() }; var client = new ScpClient(host, userName, privateKeys); Assert.AreEqual(16 * 1024U, client.BufferSize); @@ -222,9 +222,9 @@ private PrivateKeyFile GetRsaKey() } } - private PrivateKeyFile GetDsaKey() + private PrivateKeyFile GetEcdsaKey() { - using (var stream = GetData("Key.SSH2.DSA.txt")) + using (var stream = GetData("Key.ECDSA.txt")) { return new PrivateKeyFile(stream); } diff --git a/test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaDigitalSignatureTest.cs b/test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaDigitalSignatureTest.cs deleted file mode 100644 index 695ec7ab4..000000000 --- a/test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaDigitalSignatureTest.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Text; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using Renci.SshNet.Abstractions; -#if !NET6_0_OR_GREATER -using Renci.SshNet.Common; -#endif -using Renci.SshNet.Security; -using Renci.SshNet.Security.Cryptography; -using Renci.SshNet.Tests.Common; - -namespace Renci.SshNet.Tests.Classes.Security.Cryptography -{ - [TestClass] - public class DsaDigitalSignatureTest : TestBase - { - [TestMethod] - public void Verify() - { - byte[] data = Encoding.UTF8.GetBytes("Hello, World!"); - - DsaKey dsaKey = GetDsaKey("Key.DSA.txt"); - - Assert.AreEqual(1024, dsaKey.P.GetBitLength()); - Assert.AreEqual(160, dsaKey.Q.GetBitLength()); - - var digitalSignature = new DsaDigitalSignature(dsaKey); - - byte[] signedBytes = digitalSignature.Sign(data); - - // We can't compare signatures for value equality because they have a source of randomness - Assert.AreEqual(40, signedBytes.Length); - Assert.IsTrue(digitalSignature.Verify(data, signedBytes)); - - byte[] signatureToVerify = new byte[] - { - // Generated with a previous DsaDigitalSignature implementation in order to confirm consistent - // behaviour. We can't seem to validate against openssl because openssl outputs a DER signature, - // where as we want IEEE P1363 (fixed size) format. - 0x07, 0x4c, 0x5e, 0x15, 0x53, 0x36, 0x21, 0xbe, 0x5a, 0x82, 0x35, 0xd5, 0xb6, 0xe6, 0x7d, 0x2f, - 0x01, 0x2a, 0x78, 0x9b, 0x16, 0x4a, 0xe5, 0x8d, 0x85, 0xa6, 0x34, 0x56, 0x9d, 0x38, 0xd6, 0x1a, - 0xa4, 0xa1, 0x5b, 0x98, 0x7d, 0xd5, 0x35, 0x40 - }; - - Assert.IsTrue(digitalSignature.Verify(data, signatureToVerify)); - - Assert.IsFalse(digitalSignature.Verify(data, CryptoAbstraction.GenerateRandom(40))); - } - - private static DsaKey GetDsaKey(string fileName, string passPhrase = null) - { - using (var stream = GetData(fileName)) - { - return (DsaKey)new PrivateKeyFile(stream, passPhrase).Key; - } - } - } -} diff --git a/test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaKeyTest.cs b/test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaKeyTest.cs deleted file mode 100644 index 4f08eae07..000000000 --- a/test/Renci.SshNet.Tests/Classes/Security/Cryptography/DsaKeyTest.cs +++ /dev/null @@ -1,205 +0,0 @@ -using System; -using System.IO; -using System.Security.Cryptography; -using System.Text; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -#if !NET6_0_OR_GREATER -using Renci.SshNet.Common; -#endif -using Renci.SshNet.Security; -using Renci.SshNet.Tests.Common; - -namespace Renci.SshNet.Tests.Classes.Security.Cryptography -{ - [TestClass] - public class DsaKeyTest : TestBase - { - private static DsaKey GetDsaKey(string fileName, string passPhrase = null) - { - using (var stream = GetData(fileName)) - { - return (DsaKey)new PrivateKeyFile(stream, passPhrase).Key; - } - } - - // This is just to line up any differences in the assertion message. - private static void AssertEqual(byte[] actualBytes, string expectedHex) - { -#if NET - string actualHex = Convert.ToHexString(actualBytes); -#else - string actualHex = BitConverter.ToString(actualBytes).Replace("-", ""); -#endif - - Assert.AreEqual(expectedHex, actualHex, - $"{Environment.NewLine}Expected: {expectedHex}{Environment.NewLine} Actual: {actualHex}"); - } - - // These tests generated by converting the keys to PKCS8, importing them to BCL DSA, - // and printing out the expected DSAParameter values. - - // Some useful commands: - - // Generate a new params file with specific parameters: - // openssl genpkey -genparam -algorithm dsa -pkeyopt pbits:1024 -pkeyopt qbits:160 -out dsa.1024.params - - // Generate PKCS8 key file from the params: - // openssl genpkey -paramfile dsa.1024.params -out dsa.1024.txt - - // Convert to PKCS1: - // openssl pkcs8 -in dsa.1024.txt -nocrypt -traditional -out dsa.1024.pkcs1.txt - - // Convert PKCS1 to ssh.com: - // puttygen dsa.1024.pkcs1.txt -O private-sshcom -o dsa.1024.ssh2.txt - - // Convert to PKCS8: - // openssl pkcs8 -topk8 -nocrypt -in Key.DSA.txt -out Key.DSA.PKCS8.txt - - /* - - using IndentedTextWriter tw = new(Console.Out); - - foreach (string filePath in Directory.EnumerateFiles(dir, "*.DSA.*txt")) - { - string pkFile = Path.GetFileNameWithoutExtension(filePath); - - tw.WriteLine("[TestMethod]"); - tw.WriteLine($"public void {pkFile.Replace('.', '_')}()"); - tw.WriteLine("{"); - tw.Indent++; - - tw.WriteLine($"DsaKey dsaKey = GetDsaKey(\"{pkFile}.txt\");"); - tw.WriteLine(); - tw.WriteLine("DSAParameters p = dsaKey.GetDSAParameters();"); - tw.WriteLine(); - - using DSA dsa = DSA.Create(); - - dsa.ImportFromPem(File.ReadAllText(filePath)); - - DSAParameters p = dsa.ExportParameters(true); - - WriteParamAssert(p.P); - WriteParamAssert(p.G); - WriteParamAssert(p.Y); - WriteParamAssert(p.Q); - WriteParamAssert(p.X); - - tw.Indent--; - tw.WriteLine("}"); - tw.WriteLine(); - } - - void WriteParamAssert(byte[] bytes, [CallerArgumentExpression(nameof(bytes))] string name = null) - { - tw.WriteLine($"AssertEqual({name}, \"{Convert.ToHexString(bytes)}\");"); - } - */ - - [TestMethod] - public void Key_DSA() - { - DsaKey dsaKey = GetDsaKey("Key.DSA.txt"); - - Assert.AreEqual(1024, dsaKey.P.GetBitLength()); - Assert.AreEqual(160, dsaKey.Q.GetBitLength()); - - DSAParameters p = dsaKey.GetDSAParameters(); - - AssertEqual(p.P, "B565DDF69ED8EE2AC2C00AF794944A15F428C50D3FECA5FEE4F79461FD4FF669B671D296B4F19D35970A5D20F752847826849C30E12F19B8682BF5020E01FF2BDC338BB7E2A92668D2F2D8B880C62A9DA1B65C346EB53EAC2A779203929DFC2C1B27F2D99BD76C6EF4D6A5A547CE892101D5CC82AF8CC564CAE6D30B5DC89415"); - AssertEqual(p.G, "0E549E37E14011DC79FA940E6758D7C53AE5151F75BB9C968FD054098883F1EC651B7713BDAAD0CD4DB5A458BDDCF6AC79F81ECE95EE3133B72FC973EB3505180C7085952F947B6C7721E26B91D7D9907F5E3CFDB9CB9034278FDCFBC5D7BD06A3E330399DFC35DE8CB93EDC9DEDDDCAAB9B440CCF0A8957488709178D40373D"); - AssertEqual(p.Y, "9BC2066506AD4BB33A01F3484CD586E1323B6766914232DBF7F316248203EDCFD5438CDD4D9746DE4A64D068FD9F8C6B7A8A4AE4D99801D8FCAED15F3C18265E5B6C2EAB7E6C1717929C56FFFED60B6F563975B7B7DD3249387E716B967EBF5F57B99FE1097FEAEFD9220A5036F9CD61ECDACEDDDF2BC1178C8D5D01712E4311"); - AssertEqual(p.Q, "AEFA2364A9FFD838062362B1D20871665807C461"); - AssertEqual(p.X, "18463B393E02299EA1BF7AE04F3E1EC40D97275E"); - } - - - [TestMethod] - public void Key_SSH2_DSA_Encrypted_Des_CBC_12345() - { - DsaKey dsaKey = GetDsaKey("Key.SSH2.DSA.Encrypted.Des.CBC.12345.txt", "12345"); - - Assert.AreEqual(1024, dsaKey.P.GetBitLength()); - Assert.AreEqual(160, dsaKey.Q.GetBitLength()); - - DSAParameters p = dsaKey.GetDSAParameters(); - - AssertEqual(p.P, "8F20C8715C86456190F8B0921923143A8DEB0DA71564EA572F6C2E316CDFCA0458B329030F7E735DF67AB529B4084D43A2595005591A596FFF7579864B120F20A17BD598E487EC3A587A5F475C642C012B2B04CD094FC8C16A02D6DCF6EBFBA1458DCC17EF11BB55E9637F5667265DFEDDCA8DC40555DB04574F97534A0BB5BD"); - AssertEqual(p.G, "04B63D3DBA0C7F4DD97A6E8ED7EA65F5EE17205602317188F954D38D83693A20799116B88BBE261A4BAF26201E121B78E6BEFC5B5C01AA4756D6054AEFF749F4C29C7172EB8DA02172949432BAA524CD2B141DBD1631C9DC67FB4142DF8D267441D59A7DB30F27DB4A1CA60DD654F75A5D3B5CE2993CDCD601EB2C06E9414FBE"); - AssertEqual(p.Y, "17F837B9770A37DCB325F56F08BC0E1D63C435C2C85DC9C006273872FAA605F5D09CC03D4F83EE046CF8D83E6CC9A29B15ACAF7BBFD421C7261C5CCAFF887867806C1DF6760DCF348AC7AEB9BE44A3CF27895A9790F9FBCD57708B22D3F4D72A5B52B78CFACF95CF5C28AF98E82CA7034B85F4A10D1121564D1079DE92E2EE16"); - AssertEqual(p.Q, "D8D7E6D3B7BB3688D998A011380BD85D5910B279"); - AssertEqual(p.X, "23FA5A574AF1197B185B88008A7A7527899FD092"); - } - - [TestMethod] - public void Key_SSH2_DSA() - { - DsaKey dsaKey = GetDsaKey("Key.SSH2.DSA.txt"); - - Assert.AreEqual(1024, dsaKey.P.GetBitLength()); - Assert.AreEqual(160, dsaKey.Q.GetBitLength()); - - DSAParameters p = dsaKey.GetDSAParameters(); - - AssertEqual(p.P, "E0921AE3B1C58FC3401A301BB7E44B7D00266C0DE1F0CF5D3A324DA01AC70A4E5A71895C58603F8225F8648A9696B19D45A46A32A931CD5BD6185AC0F58DE2CC684FC4116FA4805B7D04AE74FFA54B6CC6AA059641656B8C6F59280D02E1C0564501AE03EC278B077A149B3459F723AABC46095EDA3C870C74CEA8F8F62845E1"); - AssertEqual(p.G, "2BBCFEC01A1E6363ECF179045BE76CF17146A644191560BFDF7AB749362F61A0CF1968EE3EF9782CF3031BA66A04721F43B1776DB9F8EA5D6A64EF2C253E371D861B1BDCCC4901E11E16D4D1B2EDBF2144CAA8A3C720E82888FCECF2AEBD0315A1575D1A0C351D6162E4A8F57FB4C1A5E92FE30BBBD324B9A166E9B8054BFC31"); - AssertEqual(p.Y, "B75F681CF20FCAFFFC99B31A629BBC23A92F8F5FFDEC48F0D2778DEC277D70664BA883C1C13C941C442F292026E01BCD3F42DEDC90E7DD115ACA14667FEF11AC0992E1DD4C8EB08EB3A7E67B22E7936913A513C5676C741F5B9D211021CD17A1C9F8FA3AC0079FB25C96BFA6A83868ABB9C87C2DED4A05B1147E60F78F3EEE4B"); - AssertEqual(p.Q, "BBE34624549755A532514F177D3328B4371DEDE3"); - AssertEqual(p.X, "66504B5D937CD2319275BA6527352A39CC2F94C4"); - } - - [TestMethod] - public void Key_DSA_3072_256() - { - // Not supported by OpenSSH but easy enough to test here. - - var keyString = """ - -----BEGIN DSA PRIVATE KEY----- - MIIE1gIBAAKCAYEA6Rb9Cogx64CZcrnP35Nr8W9sjcUqoCpSfZrJdvIhTxgyAkEl - d9U868azCTZ1QGvUuPOCGB5Ll8nRQ6QSK9bicSQ3q3C69BcjzTfZcFuZEi533wEl - 9m9xZTbMAW8643jgARKszoNWIeTGsk2JcXQ2c6+VfPOml6F7yMv3KDIpqjUQlpK+ - RoZn5Eg5R2+2VqcNwwqbP8dyQGnGmgX2hlzbWx9Cld8NTG2b0B6Taaea4zqiMLHC - MeOUh+3WkbGM+aVQ7kthQbkhTEMmZeB/zyJrlEQGmKJl/cuvx69iO8nPSIZJDSEp - sZwg6p+Fqlm0+IyaFaxJMF+SuQirYLR+ee5oor5lcWS3Szaaikz0u1ONO3ndWAmO - eEHq7BL4vuHc/SDxfO5RouhEirCUFtGwtYq/Kf7x53ccd0Jmlj1FalubKHaiyYSg - baHrvN8rFv12XDMI0vPDeOxLVaxaB3zSJTz/ZwDjUcFx7PbuWsvOoSZeagd0sCm9 - aVNQoe7dy/5YCrM7AiEA1oznSuokVWnPt9GaBlmggzk9lMjZ/XVr9MFuDzWDycsC - ggGAYVSdm43WuonZQ40M9An5oBZuWsv22ZNXFnMXzcrKkvdslWGP+za/Ipa+tm+j - YE82vuqCdGjDuDJViJbrx2FProe4J/to2Gpd0jc0uV2c1PFO0B1hDk7tkglQyhmV - q9GAQatA4XUM5cIiInseF5JxHMmfgwEKmfIUDotWnpFQImMvehHxZfI29ngrB2ND - Ba4wBIj1Ua4UqsQi2beNfope7+XSsBQm98prswjvdR6n6wg9Xkvtn4ti3lLbEHzO - ZlwnxoRxFlNE/s2RaygGySRRYAe9TPriGWeMpWirYF3/SDAQyt5qDJsPQU0fWAuF - WsuxDlOsaLmJNJNnvySwx5Qmiw4e17U+6/IKptVbOHWowq05PxZKSVYmcP5+Jbt2 - eVzozKPNGkEw6aBy18l4t+ehx7fiUha7uCPaZ+VTPodLRZE6sKT1uiKOBtPqhrsp - bxKJ3zzmF1KZpoOG++1JHzqOPL+Npokd+K3ce9vNfU7eWTYP2DuiooyF9EktJt7w - AVilAoIBgBCpFSwJxhdAIQRefnQmweW+eXRbx8KL+8t53YsPS/fQhdzIEVEi5LWz - cJ0iAU2l2Mj43AC/6yehA8KF6vJEy4LWSXNwoGVqEoSA2LxBaomLxLARqlFyfCZN - yBlUVfXDiqFw2ajRaLQKUIxWbfC6ard69brWZuS61YQd8Jrk782VAa+sQO6Ca6Ii - vtyyRjNKxbeYwKLkZydi9JFdYYR6kmVG1ge7spemMHlozza6VvNcDU3hE4T4PwbY - Ns555ihK79EWGO2zCNjhPEIN34IjN2WjbUidCBWPGgXLhw9BYyEEREhfP1QUTe2q - S3gup/j8//v46O+OZFcB6g/MZB2IFpRRSw16qM2+pNZFKVTvXs/dUq5tEXylbMCg - +7jS5eLVAkDYFwSUai4Ht9VOHGASz7VyfPfngL8nx+KLNyegB12OLwr6ho5tc9dE - Rib63kEJnsK6CzIjg1+iFblWy4pQsHnKEgvBWxk4+sLyEZFTtjCe7KjigdH6WRDH - U5ejA3bnFQIhAIkT3ff8AjkByyJg1CRkpwDCvFag1fbPXEdg1Ru1E+l/ - -----END DSA PRIVATE KEY----- - """; - - using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(keyString)); - - DsaKey dsaKey = (DsaKey)new PrivateKeyFile(stream).Key; - - Assert.AreEqual(3072, dsaKey.P.GetBitLength()); - Assert.AreEqual(256, dsaKey.Q.GetBitLength()); - - DSAParameters p = dsaKey.GetDSAParameters(); - - AssertEqual(p.P, "E916FD0A8831EB809972B9CFDF936BF16F6C8DC52AA02A527D9AC976F2214F183202412577D53CEBC6B3093675406BD4B8F382181E4B97C9D143A4122BD6E2712437AB70BAF41723CD37D9705B99122E77DF0125F66F716536CC016F3AE378E00112ACCE835621E4C6B24D8971743673AF957CF3A697A17BC8CBF7283229AA35109692BE468667E44839476FB656A70DC30A9B3FC7724069C69A05F6865CDB5B1F4295DF0D4C6D9BD01E9369A79AE33AA230B1C231E39487EDD691B18CF9A550EE4B6141B9214C432665E07FCF226B94440698A265FDCBAFC7AF623BC9CF4886490D2129B19C20EA9F85AA59B4F88C9A15AC49305F92B908AB60B47E79EE68A2BE657164B74B369A8A4CF4BB538D3B79DD58098E7841EAEC12F8BEE1DCFD20F17CEE51A2E8448AB09416D1B0B58ABF29FEF1E7771C774266963D456A5B9B2876A2C984A06DA1EBBCDF2B16FD765C3308D2F3C378EC4B55AC5A077CD2253CFF6700E351C171ECF6EE5ACBCEA1265E6A0774B029BD695350A1EEDDCBFE580AB33B"); - AssertEqual(p.G, "61549D9B8DD6BA89D9438D0CF409F9A0166E5ACBF6D99357167317CDCACA92F76C95618FFB36BF2296BEB66FA3604F36BEEA827468C3B832558896EBC7614FAE87B827FB68D86A5DD23734B95D9CD4F14ED01D610E4EED920950CA1995ABD18041AB40E1750CE5C222227B1E1792711CC99F83010A99F2140E8B569E915022632F7A11F165F236F6782B07634305AE300488F551AE14AAC422D9B78D7E8A5EEFE5D2B01426F7CA6BB308EF751EA7EB083D5E4BED9F8B62DE52DB107CCE665C27C68471165344FECD916B2806C924516007BD4CFAE219678CA568AB605DFF483010CADE6A0C9B0F414D1F580B855ACBB10E53AC68B989349367BF24B0C794268B0E1ED7B53EEBF20AA6D55B3875A8C2AD393F164A49562670FE7E25BB76795CE8CCA3CD1A4130E9A072D7C978B7E7A1C7B7E25216BBB823DA67E5533E874B45913AB0A4F5BA228E06D3EA86BB296F1289DF3CE6175299A68386FBED491F3A8E3CBF8DA6891DF8ADDC7BDBCD7D4EDE59360FD83BA2A28C85F4492D26DEF00158A5"); - AssertEqual(p.Y, "10A9152C09C6174021045E7E7426C1E5BE79745BC7C28BFBCB79DD8B0F4BF7D085DCC8115122E4B5B3709D22014DA5D8C8F8DC00BFEB27A103C285EAF244CB82D6497370A0656A128480D8BC416A898BC4B011AA51727C264DC8195455F5C38AA170D9A8D168B40A508C566DF0BA6AB77AF5BAD666E4BAD5841DF09AE4EFCD9501AFAC40EE826BA222BEDCB246334AC5B798C0A2E4672762F4915D61847A926546D607BBB297A6307968CF36BA56F35C0D4DE11384F83F06D836CE79E6284AEFD11618EDB308D8E13C420DDF82233765A36D489D08158F1A05CB870F4163210444485F3F54144DEDAA4B782EA7F8FCFFFBF8E8EF8E645701EA0FCC641D881694514B0D7AA8CDBEA4D6452954EF5ECFDD52AE6D117CA56CC0A0FBB8D2E5E2D50240D81704946A2E07B7D54E1C6012CFB5727CF7E780BF27C7E28B3727A0075D8E2F0AFA868E6D73D7444626FADE41099EC2BA0B3223835FA215B956CB8A50B079CA120BC15B1938FAC2F2119153B6309EECA8E281D1FA5910C75397A30376E715"); - AssertEqual(p.Q, "D68CE74AEA245569CFB7D19A0659A083393D94C8D9FD756BF4C16E0F3583C9CB"); - AssertEqual(p.X, "8913DDF7FC023901CB2260D42464A700C2BC56A0D5F6CF5C4760D51BB513E97F"); - } - } -}