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);
}
}
}
}