From 08aaf634c3d37ba7379aca2fb5ccb4cbb0cc6d56 Mon Sep 17 00:00:00 2001 From: olegkap_cp Date: Tue, 6 Mar 2012 19:14:58 +0000 Subject: [PATCH] Add KeyLength property to HostKeyEventArgs --- .../Renci.SshNet/Common/HostKeyEventArgs.cs | 19 +++++++++++++---- .../Renci.SshNet/ConnectionInfo.cs | 4 ++-- .../Security/Cryptography/DsaKey.cs | 18 ++++++++++++++-- .../Renci.SshNet/Security/Cryptography/Key.cs | 8 +++++++ .../Security/Cryptography/RsaKey.cs | 14 +++++++++++++ .../Renci.SshNet/Security/KeyExchange.cs | 8 +++---- .../Security/KeyExchangeDiffieHellman.cs | 21 ++++++++++--------- .../Renci.SshNet/Security/KeyHostAlgorithm.cs | 18 +++++++++------- Renci.SshClient/Renci.SshNet/Session.cs | 1 - 9 files changed, 81 insertions(+), 30 deletions(-) diff --git a/Renci.SshClient/Renci.SshNet/Common/HostKeyEventArgs.cs b/Renci.SshClient/Renci.SshNet/Common/HostKeyEventArgs.cs index 0e3868ef..b44c3165 100644 --- a/Renci.SshClient/Renci.SshNet/Common/HostKeyEventArgs.cs +++ b/Renci.SshClient/Renci.SshNet/Common/HostKeyEventArgs.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Renci.SshNet.Security.Cryptography; +using Renci.SshNet.Security; namespace Renci.SshNet.Common { @@ -29,19 +30,29 @@ namespace Renci.SshNet.Common /// public byte[] FingerPrint { get; private set; } + /// + /// Gets the length of the key in bits. + /// + /// + /// The length of the key in bits. + /// + public int KeyLength { get; private set; } + /// /// Initializes a new instance of the class. /// - /// The host key. - public HostKeyEventArgs(byte[] hostKey) + /// The host. + public HostKeyEventArgs(KeyHostAlgorithm host) { this.CanTrust = true; // Set default value - this.HostKey = hostKey; + this.HostKey = host.Data; + + this.KeyLength = host.Key.KeyLength; using (var md5 = new MD5Hash()) { - this.FingerPrint = md5.ComputeHash(hostKey); + this.FingerPrint = md5.ComputeHash(host.Data); } } } diff --git a/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs b/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs index bb35a8ed..24dc0d75 100644 --- a/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs +++ b/Renci.SshClient/Renci.SshNet/ConnectionInfo.cs @@ -38,7 +38,7 @@ namespace Renci.SshNet /// /// Gets supported host key algorithms for this connection. /// - public IDictionary> HostKeyAlgorithms { get; private set; } + public IDictionary> HostKeyAlgorithms { get; private set; } /// /// Gets supported authentication methods for this connection. @@ -282,7 +282,7 @@ namespace Renci.SshNet //{"none", typeof(...)}, }; - this.HostKeyAlgorithms = new Dictionary>() + this.HostKeyAlgorithms = new Dictionary>() { {"ssh-rsa", (data) => { return new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data); }}, {"ssh-dss", (data) => { return new KeyHostAlgorithm("ssh-dss", new DsaKey(), data); }}, diff --git a/Renci.SshClient/Renci.SshNet/Security/Cryptography/DsaKey.cs b/Renci.SshClient/Renci.SshNet/Security/Cryptography/DsaKey.cs index 36b8871e..852a183f 100644 --- a/Renci.SshClient/Renci.SshNet/Security/Cryptography/DsaKey.cs +++ b/Renci.SshClient/Renci.SshNet/Security/Cryptography/DsaKey.cs @@ -67,6 +67,20 @@ namespace Renci.SshNet.Security } } + /// + /// Gets the length of the key. + /// + /// + /// The length of the key. + /// + public override int KeyLength + { + get + { + return this.P.BitLength; + } + } + private DsaDigitalSignature _digitalSignature; /// /// Gets the digital signature. @@ -99,7 +113,7 @@ namespace Renci.SshNet.Security { if (value.Length != 4) throw new InvalidOperationException("Invalid public key."); - + this._privateKey = value; } } @@ -123,7 +137,7 @@ namespace Renci.SshNet.Security if (this._privateKey.Length != 5) throw new InvalidOperationException("Invalid private key."); } - + #region IDisposable Members private bool _isDisposed = false; diff --git a/Renci.SshClient/Renci.SshNet/Security/Cryptography/Key.cs b/Renci.SshClient/Renci.SshNet/Security/Cryptography/Key.cs index 906a1446..b22c7e7e 100644 --- a/Renci.SshClient/Renci.SshNet/Security/Cryptography/Key.cs +++ b/Renci.SshClient/Renci.SshNet/Security/Cryptography/Key.cs @@ -30,6 +30,14 @@ namespace Renci.SshNet.Security /// public abstract BigInteger[] Public { get; set; } + /// + /// Gets the length of the key. + /// + /// + /// The length of the key. + /// + public abstract int KeyLength { get; } + /// /// Initializes a new instance of the class. /// diff --git a/Renci.SshClient/Renci.SshNet/Security/Cryptography/RsaKey.cs b/Renci.SshClient/Renci.SshNet/Security/Cryptography/RsaKey.cs index 0b7b7ff7..ba1c65a2 100644 --- a/Renci.SshClient/Renci.SshNet/Security/Cryptography/RsaKey.cs +++ b/Renci.SshClient/Renci.SshNet/Security/Cryptography/RsaKey.cs @@ -118,6 +118,20 @@ namespace Renci.SshNet.Security } } + /// + /// Gets the length of the key. + /// + /// + /// The length of the key. + /// + public override int KeyLength + { + get + { + return this.Modulus.BitLength; + } + } + private RsaDigitalSignature _digitalSignature; /// /// Gets the digital signature. diff --git a/Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs b/Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs index 0dd0785f..add7267e 100644 --- a/Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs +++ b/Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs @@ -277,13 +277,13 @@ namespace Renci.SshNet.Security /// /// Determines whether the specified host key can be trusted. /// - /// The host key. + /// The host algorithm. /// - /// true if the specified host key can be trusted; otherwise, false. + /// true if the specified host can be trusted; otherwise, false. /// - protected bool CanTrustHostKey(byte[] hostKey) + protected bool CanTrustHostKey(KeyHostAlgorithm host) { - var args = new HostKeyEventArgs(hostKey); + var args = new HostKeyEventArgs(host); if (this.HostKeyReceived != null) { diff --git a/Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs b/Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs index 50e18e7a..dfc1a11e 100644 --- a/Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs +++ b/Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs @@ -71,17 +71,18 @@ namespace Renci.SshNet.Security /// protected override bool ValidateExchangeHash() { - if (this.CanTrustHostKey(this._hostKey)) + var exchangeHash = this.CalculateHash(); + + var length = (uint)(this._hostKey[0] << 24 | this._hostKey[1] << 16 | this._hostKey[2] << 8 | this._hostKey[3]); + + var algorithmName = Encoding.UTF8.GetString(this._hostKey, 4, (int)length); + + var key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](this._hostKey); + + this.Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName; + + if (this.CanTrustHostKey(key)) { - var exchangeHash = this.CalculateHash(); - - var length = (uint)(this._hostKey[0] << 24 | this._hostKey[1] << 16 | this._hostKey[2] << 8 | this._hostKey[3]); - - var algorithmName = Encoding.UTF8.GetString(this._hostKey, 4, (int)length); - - var key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](this._hostKey); - - this.Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName; return key.VerifySignature(exchangeHash, this._signature); } diff --git a/Renci.SshClient/Renci.SshNet/Security/KeyHostAlgorithm.cs b/Renci.SshClient/Renci.SshNet/Security/KeyHostAlgorithm.cs index dc92d2ea..17c070df 100644 --- a/Renci.SshClient/Renci.SshNet/Security/KeyHostAlgorithm.cs +++ b/Renci.SshClient/Renci.SshNet/Security/KeyHostAlgorithm.cs @@ -12,7 +12,11 @@ namespace Renci.SshNet.Security /// public class KeyHostAlgorithm : HostAlgorithm { - private Key _key; + + /// + /// Gets the key. + /// + public Key Key { get; private set; } /// /// Gets the public key data. @@ -21,7 +25,7 @@ namespace Renci.SshNet.Security { get { - return new SshKeyData(this.Name, this._key.Public).GetBytes(); + return new SshKeyData(this.Name, this.Key.Public).GetBytes(); } } @@ -33,7 +37,7 @@ namespace Renci.SshNet.Security public KeyHostAlgorithm(string name, Key key) : base(name) { - this._key = key; + this.Key = key; } /// @@ -45,11 +49,11 @@ namespace Renci.SshNet.Security public KeyHostAlgorithm(string name, Key key, byte[] data) : base(name) { - this._key = key; + this.Key = key; var sshKey = new SshKeyData(); sshKey.Load(data); - this._key.Public = sshKey.Keys; + this.Key.Public = sshKey.Keys; } /// @@ -59,7 +63,7 @@ namespace Renci.SshNet.Security /// public override byte[] Sign(byte[] data) { - return new SignatureKeyData(this.Name, this._key.Sign(data)).GetBytes().ToArray(); + return new SignatureKeyData(this.Name, this.Key.Sign(data)).GetBytes().ToArray(); } /// @@ -73,7 +77,7 @@ namespace Renci.SshNet.Security var signatureData = new SignatureKeyData(); signatureData.Load(signature); - return this._key.VerifySignature(data, signatureData.Signature); + return this.Key.VerifySignature(data, signatureData.Signature); } private class SshKeyData : SshData diff --git a/Renci.SshClient/Renci.SshNet/Session.cs b/Renci.SshClient/Renci.SshNet/Session.cs index e2531c28..7813db07 100644 --- a/Renci.SshClient/Renci.SshNet/Session.cs +++ b/Renci.SshClient/Renci.SshNet/Session.cs @@ -1887,7 +1887,6 @@ namespace Renci.SshNet { var contentBody = new byte[contentLength]; this.SocketRead(contentLength, ref contentBody); - var text = encoding.GetString(contentBody); } if (statusCode == 200 && string.IsNullOrEmpty(response))