diff --git a/src/Renci.SshNet/ConnectionInfo.cs b/src/Renci.SshNet/ConnectionInfo.cs index bedb5d9d5..b7806a908 100644 --- a/src/Renci.SshNet/ConnectionInfo.cs +++ b/src/Renci.SshNet/ConnectionInfo.cs @@ -407,7 +407,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 606bb00fb..f63fe05d0 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs @@ -80,8 +80,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 568170ee8..da879c3c3 100644 --- a/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs +++ b/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs @@ -83,21 +83,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 7a130e0e6..cbd037390 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -381,10 +381,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/Dockerfile b/test/Renci.SshNet.IntegrationTests/Dockerfile index d2ef74223..548f76dab 100644 --- a/test/Renci.SshNet.IntegrationTests/Dockerfile +++ b/test/Renci.SshNet.IntegrationTests/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.20 +FROM alpine:latest COPY --chown=root:root server/ssh /etc/ssh/ COPY --chown=root:root server/script /opt/sshnet 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/KeyExchangeAlgorithmTests.cs b/test/Renci.SshNet.IntegrationTests/KeyExchangeAlgorithmTests.cs index d88c9cc7d..bce4cc6d7 100644 --- a/test/Renci.SshNet.IntegrationTests/KeyExchangeAlgorithmTests.cs +++ b/test/Renci.SshNet.IntegrationTests/KeyExchangeAlgorithmTests.cs @@ -23,7 +23,6 @@ public void TearDown() } [TestMethod] - [Ignore] public void SNtruP761X25519Sha512() { _remoteSshdConfig.ClearKeyExchangeAlgorithms() 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.IntegrationTests/SshConnectionDisruptor.cs b/test/Renci.SshNet.IntegrationTests/SshConnectionDisruptor.cs index 4116daad7..ae6d4c5b8 100644 --- a/test/Renci.SshNet.IntegrationTests/SshConnectionDisruptor.cs +++ b/test/Renci.SshNet.IntegrationTests/SshConnectionDisruptor.cs @@ -22,19 +22,24 @@ public SshConnectionRestorer BreakConnections() private static void PauseSshd(SshClient client) { - var command = client.CreateCommand("sudo echo 'DenyUsers sshnet' >> /etc/ssh/sshd_config"); - var output = command.Execute(); - if (command.ExitStatus != 0) + using (var command = client.CreateCommand("sudo echo 'DenyUsers sshnet' >> /etc/ssh/sshd_config")) { - throw new ApplicationException( - $"Blocking user sshnet failed with exit code {command.ExitStatus}.\r\n{output}\r\n{command.Error}"); + var output = command.Execute(); + if (command.ExitStatus != 0) + { + throw new ApplicationException( + $"Blocking user sshnet failed with exit code {command.ExitStatus}.\r\n{output}\r\n{command.Error}"); + } } - command = client.CreateCommand("sudo pkill -9 -U sshnet -f sshd.pam"); - output = command.Execute(); - if (command.ExitStatus != 0) + + using (var command = client.CreateCommand("sudo pkill -9 -U sshnet -f sshd-session.pam")) { - throw new ApplicationException( - $"Killing sshd.pam service failed with exit code {command.ExitStatus}.\r\n{output}\r\n{command.Error}"); + var output = command.Execute(); + if (command.ExitStatus != 0) + { + throw new ApplicationException( + $"Killing sshd-session.pam service failed with exit code {command.ExitStatus}.\r\n{output}\r\n{command.Error}"); + } } } } diff --git a/test/Renci.SshNet.IntegrationTests/TestsFixtures/InfrastructureFixture.cs b/test/Renci.SshNet.IntegrationTests/TestsFixtures/InfrastructureFixture.cs index 93d44e015..47629b67f 100644 --- a/test/Renci.SshNet.IntegrationTests/TestsFixtures/InfrastructureFixture.cs +++ b/test/Renci.SshNet.IntegrationTests/TestsFixtures/InfrastructureFixture.cs @@ -75,14 +75,16 @@ public async Task DisposeAsync() { if (_sshServer != null) { +#pragma warning disable S6966 // Awaitable method should be used //try //{ - // File.WriteAllBytes(@"C:\tmp\auth.log", await _sshServer.ReadFileAsync("/var/log/auth.log")); + // File.WriteAllBytes(@"C:\tmp\auth.log", await _sshServer.ReadFileAsync("/var/log/auth.log").ConfigureAwait(false)); //} //catch (Exception ex) //{ // Console.Error.WriteLine(ex.ToString()); //} +#pragma warning restore S6966 // Awaitable method should be used await _sshServer.DisposeAsync(); } diff --git a/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs b/test/Renci.SshNet.Tests/Classes/PrivateKeyFileTest.cs index 3e0935ff6..2e5f64a3b 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))] @@ -366,8 +361,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"); - } - } -}