< Summary

Information
Class: Renci.SshNet.Security.KeyHostAlgorithm
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\KeyHostAlgorithm.cs
Line coverage
100%
Covered lines: 123
Uncovered lines: 0
Coverable lines: 123
Total lines: 323
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
get_Key()100%1100%
get_DigitalSignature()100%1100%
get_Data()100%2100%
.ctor(...)100%1100%
.ctor(...)100%1100%
.ctor(...)100%1100%
.ctor(...)100%1100%
Sign(...)100%1100%
VerifySignature(...)100%1100%
get_Keys()100%2100%
set_Keys(...)100%4100%
get_Name()100%1100%
set_Name(...)100%1100%
get_BufferCapacity()100%2100%
.ctor()100%1100%
.ctor(...)100%1100%
LoadData()100%2100%
SaveData()100%2100%
get_AlgorithmName()100%1100%
get_Signature()100%1100%
get_BufferCapacity()100%1100%
.ctor()100%1100%
.ctor(...)100%1100%
LoadData()100%1100%
SaveData()100%1100%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\KeyHostAlgorithm.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Text;
 3
 4using Renci.SshNet.Common;
 5using Renci.SshNet.Security.Chaos.NaCl;
 6using Renci.SshNet.Security.Cryptography;
 7
 8namespace Renci.SshNet.Security
 9{
 10    /// <summary>
 11    /// Implements key support for host algorithm.
 12    /// </summary>
 13    public class KeyHostAlgorithm : HostAlgorithm
 14    {
 15        /// <summary>
 16        /// Gets the key used in this host key algorithm.
 17        /// </summary>
 18        /// <value>
 19        /// The key used in this host key algorithm.
 20        /// </value>
 1043521        public Key Key { get; private set; }
 22
 23        /// <summary>
 24        /// Gets the signature implementation used in this host key algorithm.
 25        /// </summary>
 26        /// <value>
 27        /// The signature implementation used in this host key algorithm.
 28        /// </value>
 472329        public DigitalSignature DigitalSignature { get; private set; }
 30
 31        /// <summary>
 32        /// Gets the encoded public key data.
 33        /// </summary>
 34        /// <value>
 35        /// The encoded public key data.
 36        /// </value>
 37        public override byte[] Data
 38        {
 39            get
 259040            {
 259041                var keyFormatIdentifier = Key is RsaKey ? "ssh-rsa" : Name;
 259042                return new SshKeyData(keyFormatIdentifier, Key.Public).GetBytes();
 259043            }
 44        }
 45
 46        /// <summary>
 47        /// Initializes a new instance of the <see cref="KeyHostAlgorithm"/> class.
 48        /// </summary>
 49        /// <param name="name">The signature format identifier.</param>
 50        /// <param name="key"><inheritdoc cref="Key" path="/summary"/></param>
 51        /// <remarks>
 52        /// This constructor is typically passed a private key in order to create an encoded signature for later
 53        /// verification by the host.
 54        /// </remarks>
 55        public KeyHostAlgorithm(string name, Key key)
 57656            : base(name)
 57657        {
 57658            Key = key;
 57659            DigitalSignature = key.DigitalSignature;
 57660        }
 61
 62        /// <summary>
 63        /// Initializes a new instance of the <see cref="KeyHostAlgorithm"/> class.
 64        /// </summary>
 65        /// <param name="name">The signature format identifier.</param>
 66        /// <param name="key"><inheritdoc cref="Key" path="/summary"/></param>
 67        /// <param name="digitalSignature"><inheritdoc cref="DigitalSignature" path="/summary"/></param>
 68        /// <remarks>
 69        /// <para>
 70        /// This constructor is typically passed a private key in order to create an encoded signature for later
 71        /// verification by the host.
 72        /// </para>
 73        /// The key used by <paramref name="digitalSignature"/> is intended to be equal to <paramref name="key"/>.
 74        /// This is not verified.
 75        /// </remarks>
 76        public KeyHostAlgorithm(string name, Key key, DigitalSignature digitalSignature)
 103777            : base(name)
 103778        {
 103779            Key = key;
 103780            DigitalSignature = digitalSignature;
 103781        }
 82
 83        /// <summary>
 84        /// Initializes a new instance of the <see cref="KeyHostAlgorithm"/> class
 85        /// with the given encoded public key data. The data will be decoded into <paramref name="key"/>.
 86        /// </summary>
 87        /// <param name="name">The signature format identifier.</param>
 88        /// <param name="key"><inheritdoc cref="Key" path="/summary"/></param>
 89        /// <param name="data">Host key encoded data.</param>
 90        /// <remarks>
 91        /// This constructor is typically passed a new or reusable <see cref="Security.Key"/> instance in
 92        /// order to verify an encoded signature sent by the host, created by the private counterpart
 93        /// to the host's public key, which is encoded in <paramref name="data"/>.
 94        /// </remarks>
 95        public KeyHostAlgorithm(string name, Key key, byte[] data)
 1296            : base(name)
 1297        {
 1298            Key = key;
 99
 12100            var sshKey = new SshKeyData();
 12101            sshKey.Load(data);
 12102            Key.Public = sshKey.Keys;
 103
 12104            DigitalSignature = key.DigitalSignature;
 12105        }
 106
 107        /// <summary>
 108        /// Initializes a new instance of the <see cref="KeyHostAlgorithm"/> class
 109        /// with the given encoded public key data. The data will be decoded into <paramref name="key"/>.
 110        /// </summary>
 111        /// <param name="name">The signature format identifier.</param>
 112        /// <param name="key"><inheritdoc cref="Key" path="/summary"/></param>
 113        /// <param name="data">Host key encoded data.</param>
 114        /// <param name="digitalSignature"><inheritdoc cref="DigitalSignature" path="/summary"/></param>
 115        /// <remarks>
 116        /// <para>
 117        /// This constructor is typically passed a new or reusable <see cref="Security.Key"/> instance in
 118        /// order to verify an encoded signature sent by the host, created by the private counterpart
 119        /// to the host's public key, which is encoded in <paramref name="data"/>.
 120        /// </para>
 121        /// The key used by <paramref name="digitalSignature"/> is intended to be equal to <paramref name="key"/>.
 122        /// This is not verified.
 123        /// </remarks>
 124        public KeyHostAlgorithm(string name, Key key, byte[] data, DigitalSignature digitalSignature)
 1196125            : base(name)
 1196126        {
 1196127            Key = key;
 128
 1196129            var sshKey = new SshKeyData();
 1196130            sshKey.Load(data);
 1196131            Key.Public = sshKey.Keys;
 132
 1196133            DigitalSignature = digitalSignature;
 1196134        }
 135
 136        /// <summary>
 137        /// Signs and encodes the specified data.
 138        /// </summary>
 139        /// <param name="data">The data to be signed.</param>
 140        /// <returns>
 141        /// The encoded signature.
 142        /// </returns>
 143        public override byte[] Sign(byte[] data)
 689144        {
 689145            return new SignatureKeyData(Name, DigitalSignature.Sign(data)).GetBytes();
 689146        }
 147
 148        /// <summary>
 149        /// Verifies the signature.
 150        /// </summary>
 151        /// <param name="data">The data to verify the signature against.</param>
 152        /// <param name="signature">The encoded signature data.</param>
 153        /// <returns>
 154        /// <see langword="true"/> if <paramref name="signature"/> is the result of signing <paramref name="data"/>
 155        /// with the corresponding private key to <see cref="Key"/>.
 156        /// </returns>
 157        public override bool VerifySignature(byte[] data, byte[] signature)
 9158        {
 9159            var signatureData = new SignatureKeyData();
 9160            signatureData.Load(signature);
 161
 9162            return DigitalSignature.Verify(data, signatureData.Signature);
 9163        }
 164
 165        private sealed class SshKeyData : SshData
 166        {
 167            private byte[] _name;
 168            private List<byte[]> _keys;
 169
 170            public BigInteger[] Keys
 171            {
 172                get
 1208173                {
 1208174                    var keys = new BigInteger[_keys.Count];
 175
 7254176                    for (var i = 0; i < _keys.Count; i++)
 2419177                    {
 2419178                        var key = _keys[i];
 2419179                        keys[i] = key.ToBigInteger2();
 2419180                    }
 181
 1208182                    return keys;
 1208183                }
 184                private set
 2590185                {
 2590186                    _keys = new List<byte[]>(value.Length);
 187
 18138188                    foreach (var key in value)
 5184189                    {
 5184190                        var keyData = key.ToByteArray().Reverse();
 5184191                        if (Name == "ssh-ed25519")
 4192                        {
 4193                            keyData = keyData.TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes);
 4194                        }
 195
 5184196                        _keys.Add(keyData);
 5184197                    }
 2590198                }
 199            }
 200
 201            private string Name
 202            {
 15552203                get { return Utf8.GetString(_name, 0, _name.Length); }
 7770204                set { _name = Utf8.GetBytes(value); }
 205            }
 206
 207            protected override int BufferCapacity
 208            {
 209                get
 2590210                {
 2590211                    var capacity = base.BufferCapacity;
 2590212                    capacity += 4; // Name length
 2590213                    capacity += _name.Length; // Name
 214
 18138215                    foreach (var key in _keys)
 5184216                    {
 5184217                        capacity += 4; // Key length
 5184218                        capacity += key.Length; // Key
 5184219                    }
 220
 2590221                    return capacity;
 2590222                }
 223            }
 224
 1208225            public SshKeyData()
 1208226            {
 1208227            }
 228
 2590229            public SshKeyData(string name, params BigInteger[] keys)
 2590230            {
 2590231                Name = name;
 2590232                Keys = keys;
 2590233            }
 234
 235            protected override void LoadData()
 1208236            {
 1208237                _name = ReadBinary();
 1208238                _keys = new List<byte[]>();
 239
 3627240                while (!IsEndOfData)
 2419241                {
 2419242                    _keys.Add(ReadBinary());
 2419243                }
 1208244            }
 245
 246            protected override void SaveData()
 2590247            {
 2590248                WriteBinaryString(_name);
 249
 18138250                foreach (var key in _keys)
 5184251                {
 5184252                    WriteBinaryString(key);
 5184253                }
 2590254            }
 255        }
 256
 257        internal sealed class SignatureKeyData : SshData
 258        {
 259            /// <summary>
 260            /// Gets or sets the signature format identifier.
 261            /// </summary>
 262            /// <value>
 263            /// The signature format identifier.
 264            /// </value>
 5673265            public string AlgorithmName { get; set; }
 266
 267            /// <summary>
 268            /// Gets the signature.
 269            /// </summary>
 270            /// <value>
 271            /// The signature.
 272            /// </value>
 4482273            public byte[] Signature { get; private set; }
 274
 275            /// <summary>
 276            /// Gets the size of the message in bytes.
 277            /// </summary>
 278            /// <value>
 279            /// The size of the messages in bytes.
 280            /// </value>
 281            protected override int BufferCapacity
 282            {
 283                get
 689284                {
 689285                    var capacity = base.BufferCapacity;
 689286                    capacity += 4; // AlgorithmName length
 689287                    capacity += Encoding.UTF8.GetByteCount(AlgorithmName); // AlgorithmName
 689288                    capacity += 4; // Signature length
 689289                    capacity += Signature.Length; // Signature
 689290                    return capacity;
 689291                }
 292            }
 293
 1208294            public SignatureKeyData()
 1208295            {
 1208296            }
 297
 689298            public SignatureKeyData(string name, byte[] signature)
 689299            {
 689300                AlgorithmName = name;
 689301                Signature = signature;
 689302            }
 303
 304            /// <summary>
 305            /// Called when type specific data need to be loaded.
 306            /// </summary>
 307            protected override void LoadData()
 1208308            {
 1208309                AlgorithmName = Encoding.UTF8.GetString(ReadBinary());
 1208310                Signature = ReadBinary();
 1208311            }
 312
 313            /// <summary>
 314            /// Called when type specific data need to be saved.
 315            /// </summary>
 316            protected override void SaveData()
 689317            {
 689318                WriteBinaryString(Encoding.UTF8.GetBytes(AlgorithmName));
 689319                WriteBinaryString(Signature);
 689320            }
 321        }
 322    }
 323}