浏览代码

Add KeyLength property to HostKeyEventArgs

olegkap_cp 13 年之前
父节点
当前提交
08aaf634c3

+ 15 - 4
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
         /// </summary>
         public byte[] FingerPrint { get; private set; }
 
+        /// <summary>
+        /// Gets the length of the key in bits.
+        /// </summary>
+        /// <value>
+        /// The length of the key in bits.
+        /// </value>
+        public int KeyLength { get; private set; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="HostKeyEventArgs"/> class.
         /// </summary>
-        /// <param name="hostKey">The host key.</param>
-        public HostKeyEventArgs(byte[] hostKey)
+        /// <param name="host">The host.</param>
+        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);
             }
         }
     }

+ 2 - 2
Renci.SshClient/Renci.SshNet/ConnectionInfo.cs

@@ -38,7 +38,7 @@ namespace Renci.SshNet
         /// <summary>
         /// Gets supported host key algorithms for this connection.
         /// </summary>
-        public IDictionary<string, Func<byte[], HostAlgorithm>> HostKeyAlgorithms { get; private set; }
+        public IDictionary<string, Func<byte[], KeyHostAlgorithm>> HostKeyAlgorithms { get; private set; }
 
         /// <summary>
         /// Gets supported authentication methods for this connection.
@@ -282,7 +282,7 @@ namespace Renci.SshNet
                 //{"none", typeof(...)},
             };
 
-            this.HostKeyAlgorithms = new Dictionary<string, Func<byte[], HostAlgorithm>>()
+            this.HostKeyAlgorithms = new Dictionary<string, Func<byte[], KeyHostAlgorithm>>()
             {
                 {"ssh-rsa", (data) => { return new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data); }},
                 {"ssh-dss", (data) => { return new KeyHostAlgorithm("ssh-dss", new DsaKey(), data); }},

+ 16 - 2
Renci.SshClient/Renci.SshNet/Security/Cryptography/DsaKey.cs

@@ -67,6 +67,20 @@ namespace Renci.SshNet.Security
             }
         }
 
+        /// <summary>
+        /// Gets the length of the key.
+        /// </summary>
+        /// <value>
+        /// The length of the key.
+        /// </value>
+        public override int KeyLength
+        {
+            get
+            {
+                return this.P.BitLength;
+            }
+        }
+
         private DsaDigitalSignature _digitalSignature;
         /// <summary>
         /// 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;

+ 8 - 0
Renci.SshClient/Renci.SshNet/Security/Cryptography/Key.cs

@@ -30,6 +30,14 @@ namespace Renci.SshNet.Security
         /// </value>
         public abstract BigInteger[] Public { get; set; }
 
+        /// <summary>
+        /// Gets the length of the key.
+        /// </summary>
+        /// <value>
+        /// The length of the key.
+        /// </value>
+        public abstract int KeyLength { get; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="Key"/> class.
         /// </summary>

+ 14 - 0
Renci.SshClient/Renci.SshNet/Security/Cryptography/RsaKey.cs

@@ -118,6 +118,20 @@ namespace Renci.SshNet.Security
             }
         }
 
+        /// <summary>
+        /// Gets the length of the key.
+        /// </summary>
+        /// <value>
+        /// The length of the key.
+        /// </value>
+        public override int KeyLength
+        {
+            get
+            {
+                return this.Modulus.BitLength;
+            }
+        }
+
         private RsaDigitalSignature _digitalSignature;
         /// <summary>
         /// Gets the digital signature.

+ 4 - 4
Renci.SshClient/Renci.SshNet/Security/KeyExchange.cs

@@ -277,13 +277,13 @@ namespace Renci.SshNet.Security
         /// <summary>
         /// Determines whether the specified host key can be trusted.
         /// </summary>
-        /// <param name="hostKey">The host key.</param>
+        /// <param name="host">The host algorithm.</param>
         /// <returns>
-        ///   <c>true</c> if the specified host key can be trusted; otherwise, <c>false</c>.
+        ///   <c>true</c> if the specified host can be trusted; otherwise, <c>false</c>.
         /// </returns>
-        protected bool CanTrustHostKey(byte[] hostKey)
+        protected bool CanTrustHostKey(KeyHostAlgorithm host)
         {
-            var args = new HostKeyEventArgs(hostKey);
+            var args = new HostKeyEventArgs(host);
 
             if (this.HostKeyReceived != null)
             {

+ 8 - 7
Renci.SshClient/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs

@@ -71,17 +71,18 @@ namespace Renci.SshNet.Security
         /// </returns>
         protected override bool ValidateExchangeHash()
         {
-            if (this.CanTrustHostKey(this._hostKey))
-            {
-                var exchangeHash = this.CalculateHash();
+            var exchangeHash = this.CalculateHash();
+
+            var length = (uint)(this._hostKey[0] << 24 | this._hostKey[1] << 16 | this._hostKey[2] << 8 | this._hostKey[3]);
 
-                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 algorithmName = Encoding.UTF8.GetString(this._hostKey, 4, (int)length);
+            var key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](this._hostKey);
 
-                var key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName](this._hostKey);
+            this.Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName;
 
-                this.Session.ConnectionInfo.CurrentHostKeyAlgorithm = algorithmName;
+            if (this.CanTrustHostKey(key))
+            {
 
                 return key.VerifySignature(exchangeHash, this._signature);
             }

+ 11 - 7
Renci.SshClient/Renci.SshNet/Security/KeyHostAlgorithm.cs

@@ -12,7 +12,11 @@ namespace Renci.SshNet.Security
     /// </summary>
     public class KeyHostAlgorithm : HostAlgorithm
     {
-        private Key _key;
+
+        /// <summary>
+        /// Gets the key.
+        /// </summary>
+        public Key Key { get; private set; }
 
         /// <summary>
         /// 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;
         }
 
         /// <summary>
@@ -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;
         }
 
         /// <summary>
@@ -59,7 +63,7 @@ namespace Renci.SshNet.Security
         /// <returns></returns>
         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();
         }
 
         /// <summary>
@@ -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

+ 0 - 1
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))