using System.Collections.Generic; using Renci.SshNet.Common; namespace Renci.SshNet.Security { /// /// Implements key support for host algorithm. /// public class KeyHostAlgorithm : HostAlgorithm { /// /// Gets the key. /// public Key Key { get; private set; } /// /// Gets the public key data. /// public override byte[] Data { get { return new SshKeyData(this.Name, this.Key.Public).GetBytes(); } } /// /// Initializes a new instance of the class. /// /// Host key name. /// Host key. public KeyHostAlgorithm(string name, Key key) : base(name) { this.Key = key; } /// /// Initializes a new instance of the class. /// /// Host key name. /// Host key. /// Host key encoded data. public KeyHostAlgorithm(string name, Key key, byte[] data) : base(name) { this.Key = key; var sshKey = new SshKeyData(); sshKey.Load(data); this.Key.Public = sshKey.Keys; } /// /// Signs the specified data. /// /// The data. /// /// Signed data. /// public override byte[] Sign(byte[] data) { return new SignatureKeyData(this.Name, this.Key.Sign(data)).GetBytes(); } /// /// Verifies the signature. /// /// The data. /// The signature. /// /// True is signature was successfully verifies; otherwise false. /// public override bool VerifySignature(byte[] data, byte[] signature) { var signatureData = new SignatureKeyData(); signatureData.Load(signature); return this.Key.VerifySignature(data, signatureData.Signature); } private class SshKeyData : SshData { public BigInteger[] Keys { get; private set; } private string Name { get; set; } public SshKeyData() { } public SshKeyData(string name, params BigInteger[] keys) { this.Name = name; this.Keys = keys; } protected override void LoadData() { this.Name = this.ReadString(); var keys = new List(); while (!this.IsEndOfData) { keys.Add(this.ReadBigInt()); } this.Keys = keys.ToArray(); } protected override void SaveData() { this.Write(this.Name); foreach (var key in this.Keys) { this.Write(key); } } } private class SignatureKeyData : SshData { /// /// Gets or sets the name of the algorithm. /// /// /// The name of the algorithm. /// private string AlgorithmName { get; set; } /// /// Gets or sets the signature. /// /// /// The signature. /// public byte[] Signature { get; private set; } public SignatureKeyData() { } public SignatureKeyData(string name, byte[] signature) { this.AlgorithmName = name; this.Signature = signature; } /// /// Called when type specific data need to be loaded. /// protected override void LoadData() { this.AlgorithmName = this.ReadString(); this.Signature = this.ReadBinaryString(); } /// /// Called when type specific data need to be saved. /// protected override void SaveData() { this.Write(this.AlgorithmName); this.WriteBinaryString(this.Signature); } } } }