using System.Collections.Generic;
using System.Text;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Renci.SshNet.Common;
namespace Renci.SshNet.Security
{
///
/// Facilitates (de)serializing encoded public key data in the format
/// specified by RFC 4253 section 6.6.
///
///
/// See https://datatracker.ietf.org/doc/html/rfc4253#section-6.6.
///
public sealed class SshKeyData : SshData
{
///
/// Gets the public key format identifier.
///
public string Name { get; private set; }
///
/// Gets the public key constituents.
///
public BigInteger[] Keys { get; private set; }
///
protected override int BufferCapacity
{
get
{
var capacity = base.BufferCapacity;
capacity += 4; // Name length
capacity += Encoding.UTF8.GetByteCount(Name); // Name
foreach (var key in Keys)
{
capacity += 4; // Key length
capacity += key.BitLength / 8; // Key
}
return capacity;
}
}
///
/// Initializes a new instance of the class.
///
/// The encoded public key data.
public SshKeyData(byte[] data)
{
Load(data);
}
///
/// Initializes a new instance of the class.
///
/// The public key format identifer.
/// The public key constituents.
public SshKeyData(string name, BigInteger[] keys)
{
Name = name;
Keys = keys;
}
///
protected override void LoadData()
{
Name = ReadString();
var keys = new List();
while (!IsEndOfData)
{
keys.Add(ReadBinary().ToBigInteger2());
}
Keys = keys.ToArray();
}
///
protected override void SaveData()
{
Write(Name);
foreach (var key in Keys)
{
var keyData = key.ToByteArray().Reverse();
if (Name == "ssh-ed25519")
{
keyData = keyData.TrimLeadingZeros().Pad(Ed25519.PublicKeySize);
}
WriteBinaryString(keyData);
}
}
}
}