<PackageReference Include="SSH.NET" Version="2023.0.0" />

KeyHostAlgorithm

Implements key support for host algorithm.
using Renci.SshNet.Common; using Renci.SshNet.Security.Chaos.NaCl; using Renci.SshNet.Security.Cryptography; using System.Collections.Generic; using System.Text; namespace Renci.SshNet.Security { public class KeyHostAlgorithm : HostAlgorithm { private sealed class SshKeyData : SshData { private byte[] _name; private List<byte[]> _keys; public BigInteger[] Keys { get { BigInteger[] array = new BigInteger[_keys.Count]; for (int i = 0; i < _keys.Count; i++) { byte[] data = _keys[i]; array[i] = data.ToBigInteger2(); } return array; } private set { _keys = new List<byte[]>(value.Length); for (int i = 0; i < value.Length; i++) { BigInteger bigInteger = value[i]; byte[] array = bigInteger.ToByteArray().Reverse(); if (Name == "ssh-ed25519") array = array.TrimLeadingZeros().Pad(Ed25519.PublicKeySizeInBytes); _keys.Add(array); } } } private string Name { get { return SshData.Utf8.GetString(_name, 0, _name.Length); } set { _name = SshData.Utf8.GetBytes(value); } } protected override int BufferCapacity { get { int bufferCapacity = base.BufferCapacity; bufferCapacity += 4; bufferCapacity += _name.Length; foreach (byte[] key in _keys) { bufferCapacity += 4; bufferCapacity += key.Length; } return bufferCapacity; } } public SshKeyData() { } public SshKeyData(string name, params BigInteger[] keys) { Name = name; Keys = keys; } protected override void LoadData() { _name = ReadBinary(); _keys = new List<byte[]>(); while (!base.IsEndOfData) { _keys.Add(ReadBinary()); } } protected override void SaveData() { WriteBinaryString(_name); foreach (byte[] key in _keys) { WriteBinaryString(key); } } } internal sealed class SignatureKeyData : SshData { public string AlgorithmName { get; set; } public byte[] Signature { get; set; } protected override int BufferCapacity => base.BufferCapacity + 4 + Encoding.UTF8.GetByteCount(AlgorithmName) + 4 + Signature.Length; public SignatureKeyData() { } public SignatureKeyData(string name, byte[] signature) { AlgorithmName = name; Signature = signature; } protected override void LoadData() { AlgorithmName = Encoding.UTF8.GetString(ReadBinary()); Signature = ReadBinary(); } protected override void SaveData() { WriteBinaryString(Encoding.UTF8.GetBytes(AlgorithmName)); WriteBinaryString(Signature); } } public Key Key { get; set; } public DigitalSignature DigitalSignature { get; set; } public override byte[] Data => new SshKeyData((Key is RsaKey) ? "ssh-rsa" : base.Name, Key.Public).GetBytes(); public KeyHostAlgorithm(string name, Key key) : base(name) { Key = key; DigitalSignature = key.DigitalSignature; } public KeyHostAlgorithm(string name, Key key, DigitalSignature digitalSignature) : base(name) { Key = key; DigitalSignature = digitalSignature; } public KeyHostAlgorithm(string name, Key key, byte[] data) : base(name) { Key = key; SshKeyData sshKeyData = new SshKeyData(); sshKeyData.Load(data); Key.Public = sshKeyData.Keys; DigitalSignature = key.DigitalSignature; } public KeyHostAlgorithm(string name, Key key, byte[] data, DigitalSignature digitalSignature) : base(name) { Key = key; SshKeyData sshKeyData = new SshKeyData(); sshKeyData.Load(data); Key.Public = sshKeyData.Keys; DigitalSignature = digitalSignature; } public override byte[] Sign(byte[] data) { return new SignatureKeyData(base.Name, DigitalSignature.Sign(data)).GetBytes(); } public override bool VerifySignature(byte[] data, byte[] signature) { SignatureKeyData signatureKeyData = new SignatureKeyData(); signatureKeyData.Load(signature); return DigitalSignature.Verify(data, signatureKeyData.Signature); } } }