2
0

KeyHostAlgorithm.cs 5.0 KB

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