KeyHostAlgorithm.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Renci.SshNet.Common;
  6. using Renci.SshNet.Security.Cryptography;
  7. namespace Renci.SshNet.Security
  8. {
  9. /// <summary>
  10. /// Implements key support for host algorithm.
  11. /// </summary>
  12. public class KeyHostAlgorithm : HostAlgorithm
  13. {
  14. /// <summary>
  15. /// Gets the key.
  16. /// </summary>
  17. public Key Key { get; private set; }
  18. /// <summary>
  19. /// Gets the public key data.
  20. /// </summary>
  21. public override byte[] Data
  22. {
  23. get
  24. {
  25. return new SshKeyData(this.Name, this.Key.Public).GetBytes();
  26. }
  27. }
  28. /// <summary>
  29. /// Initializes a new instance of the <see cref="KeyHostAlgorithm"/> class.
  30. /// </summary>
  31. /// <param name="name">Host key name.</param>
  32. /// <param name="key">Host key.</param>
  33. public KeyHostAlgorithm(string name, Key key)
  34. : base(name)
  35. {
  36. this.Key = key;
  37. }
  38. /// <summary>
  39. /// Initializes a new instance of the <see cref="HostAlgorithm"/> class.
  40. /// </summary>
  41. /// <param name="name">Host key name.</param>
  42. /// <param name="key">Host key.</param>
  43. /// <param name="data">Host key encoded data.</param>
  44. public KeyHostAlgorithm(string name, Key key, byte[] data)
  45. : base(name)
  46. {
  47. this.Key = key;
  48. var sshKey = new SshKeyData();
  49. sshKey.Load(data);
  50. this.Key.Public = sshKey.Keys;
  51. }
  52. /// <summary>
  53. /// Signs the specified data.
  54. /// </summary>
  55. /// <param name="data">The data.</param>
  56. /// <returns>
  57. /// Signed data.
  58. /// </returns>
  59. public override byte[] Sign(byte[] data)
  60. {
  61. return new SignatureKeyData(this.Name, this.Key.Sign(data)).GetBytes().ToArray();
  62. }
  63. /// <summary>
  64. /// Verifies the signature.
  65. /// </summary>
  66. /// <param name="data">The data.</param>
  67. /// <param name="signature">The signature.</param>
  68. /// <returns>
  69. /// <c>True</c> is signature was successfully verifies; otherwise <c>false</c>.
  70. /// </returns>
  71. public override bool VerifySignature(byte[] data, byte[] signature)
  72. {
  73. var signatureData = new SignatureKeyData();
  74. signatureData.Load(signature);
  75. return this.Key.VerifySignature(data, signatureData.Signature);
  76. }
  77. private class SshKeyData : SshData
  78. {
  79. public BigInteger[] Keys { get; private set; }
  80. public string Name { get; private set; }
  81. public SshKeyData()
  82. {
  83. }
  84. public SshKeyData(string name, params BigInteger[] keys)
  85. {
  86. this.Name = name;
  87. this.Keys = keys;
  88. }
  89. protected override void LoadData()
  90. {
  91. this.Name = this.ReadString();
  92. var keys = new List<BigInteger>();
  93. while (!this.IsEndOfData)
  94. {
  95. keys.Add(this.ReadBigInt());
  96. }
  97. this.Keys = keys.ToArray();
  98. }
  99. protected override void SaveData()
  100. {
  101. this.Write(this.Name);
  102. foreach (var key in this.Keys)
  103. {
  104. this.Write(key);
  105. }
  106. }
  107. }
  108. private class SignatureKeyData : SshData
  109. {
  110. /// <summary>
  111. /// Gets or sets the name of the algorithm.
  112. /// </summary>
  113. /// <value>
  114. /// The name of the algorithm.
  115. /// </value>
  116. public string AlgorithmName { get; private set; }
  117. /// <summary>
  118. /// Gets or sets the signature.
  119. /// </summary>
  120. /// <value>
  121. /// The signature.
  122. /// </value>
  123. public byte[] Signature { get; private set; }
  124. public SignatureKeyData()
  125. {
  126. }
  127. public SignatureKeyData(string name, byte[] signature)
  128. {
  129. this.AlgorithmName = name;
  130. this.Signature = signature;
  131. }
  132. /// <summary>
  133. /// Called when type specific data need to be loaded.
  134. /// </summary>
  135. protected override void LoadData()
  136. {
  137. this.AlgorithmName = this.ReadString();
  138. this.Signature = this.ReadBinaryString();
  139. }
  140. /// <summary>
  141. /// Called when type specific data need to be saved.
  142. /// </summary>
  143. protected override void SaveData()
  144. {
  145. this.Write(this.AlgorithmName);
  146. this.WriteBinaryString(this.Signature);
  147. }
  148. }
  149. }
  150. }