CryptoPublicKeyDss.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Security.Cryptography;
  6. using Renci.SshNet.Common;
  7. using Renci.SshNet.Security.Cryptography;
  8. namespace Renci.SshNet.Security
  9. {
  10. /// <summary>
  11. /// Represents DSS public key
  12. /// </summary>
  13. public class CryptoPublicKeyDss : CryptoPublicKey
  14. {
  15. private byte[] _p;
  16. private byte[] _q;
  17. private byte[] _g;
  18. private byte[] _publicKey;
  19. /// <summary>
  20. /// Gets key name.
  21. /// </summary>
  22. public override string Name
  23. {
  24. get { return "ssh-dss"; }
  25. }
  26. /// <summary>
  27. /// Initializes a new instance of the <see cref="CryptoPublicKeyDss"/> class.
  28. /// </summary>
  29. public CryptoPublicKeyDss()
  30. {
  31. }
  32. /// <summary>
  33. /// Initializes a new instance of the <see cref="CryptoPublicKeyDss"/> class.
  34. /// </summary>
  35. /// <param name="p">The p value.</param>
  36. /// <param name="q">The q value.</param>
  37. /// <param name="g">The g value.</param>
  38. /// <param name="publicKey">The public key value.</param>
  39. public CryptoPublicKeyDss(byte[] p, byte[] q, byte[] g, byte[] publicKey)
  40. {
  41. this._p = p;
  42. this._q = q;
  43. this._g = g;
  44. this._publicKey = publicKey;
  45. }
  46. /// <summary>
  47. /// Loads key specific data.
  48. /// </summary>
  49. /// <param name="data">The data.</param>
  50. public override void Load(IEnumerable<byte> data)
  51. {
  52. MemoryStream ms = null;
  53. try
  54. {
  55. ms = new MemoryStream(data.ToArray());
  56. using (var br = new BinaryReader(ms))
  57. {
  58. var pl = (uint)(br.ReadByte() << 24 | br.ReadByte() << 16 | br.ReadByte() << 8 | br.ReadByte());
  59. _p = br.ReadBytes((int)pl);
  60. var ql = (uint)(br.ReadByte() << 24 | br.ReadByte() << 16 | br.ReadByte() << 8 | br.ReadByte());
  61. _q = br.ReadBytes((int)ql);
  62. var gl = (uint)(br.ReadByte() << 24 | br.ReadByte() << 16 | br.ReadByte() << 8 | br.ReadByte());
  63. _g = br.ReadBytes((int)gl);
  64. var xl = (uint)(br.ReadByte() << 24 | br.ReadByte() << 16 | br.ReadByte() << 8 | br.ReadByte());
  65. _publicKey = br.ReadBytes((int)xl);
  66. }
  67. }
  68. finally
  69. {
  70. if (ms != null)
  71. {
  72. ms.Dispose();
  73. ms = null;
  74. }
  75. }
  76. }
  77. /// <summary>
  78. /// Verifies the signature.
  79. /// </summary>
  80. /// <param name="hash">The hash.</param>
  81. /// <param name="signature">The signature.</param>
  82. /// <returns>
  83. /// true if signature verified; otherwise false.
  84. /// </returns>
  85. public override bool VerifySignature(IEnumerable<byte> hash, IEnumerable<byte> signature)
  86. {
  87. long i = 0;
  88. long j = 0;
  89. byte[] tmp;
  90. var sig = signature.ToArray();
  91. if (sig[0] == 0 && sig[1] == 0 && sig[2] == 0)
  92. {
  93. long i1 = (sig[i++] << 24) & 0xff000000;
  94. long i2 = (sig[i++] << 16) & 0x00ff0000;
  95. long i3 = (sig[i++] << 8) & 0x0000ff00;
  96. long i4 = (sig[i++]) & 0x000000ff;
  97. j = i1 | i2 | i3 | i4;
  98. i += j;
  99. i1 = (sig[i++] << 24) & 0xff000000;
  100. i2 = (sig[i++] << 16) & 0x00ff0000;
  101. i3 = (sig[i++] << 8) & 0x0000ff00;
  102. i4 = (sig[i++]) & 0x000000ff;
  103. j = i1 | i2 | i3 | i4;
  104. tmp = new byte[j];
  105. Array.Copy(sig, (int)i, tmp, 0, (int)j);
  106. sig = tmp;
  107. }
  108. var sig1 = new DsaDigitalSignature(_p, _q, _g, null, _publicKey);
  109. return sig1.VerifySignature(hash.ToArray(), sig);
  110. }
  111. /// <summary>
  112. /// Gets key data byte array.
  113. /// </summary>
  114. /// <returns>
  115. /// The data byte array.
  116. /// </returns>
  117. public override IEnumerable<byte> GetBytes()
  118. {
  119. return new DsaPublicKeyData
  120. {
  121. P = this._p,
  122. Q = this._q,
  123. G = this._g,
  124. Public = this._publicKey,
  125. }.GetBytes();
  126. }
  127. private class DsaPublicKeyData : SshData
  128. {
  129. public byte[] P { get; set; }
  130. public byte[] Q { get; set; }
  131. public byte[] G { get; set; }
  132. public byte[] Public { get; set; }
  133. protected override void LoadData()
  134. {
  135. }
  136. protected override void SaveData()
  137. {
  138. this.Write("ssh-dss");
  139. this.WriteBinaryString(this.P);
  140. this.WriteBinaryString(this.Q);
  141. this.WriteBinaryString(this.G);
  142. this.WriteBinaryString(this.Public);
  143. }
  144. }
  145. }
  146. }