CryptoPublicKeyRsa.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 RSA public key
  12. /// </summary>
  13. internal class CryptoPublicKeyRsa : CryptoPublicKey
  14. {
  15. private byte[] _modulus;
  16. private byte[] _exponent;
  17. /// <summary>
  18. /// Gets key name.
  19. /// </summary>
  20. public override string Name
  21. {
  22. get { return "ssh-rsa"; }
  23. }
  24. /// <summary>
  25. /// Initializes a new instance of the <see cref="CryptoPublicKeyRsa"/> class.
  26. /// </summary>
  27. public CryptoPublicKeyRsa()
  28. {
  29. }
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="CryptoPublicKeyRsa"/> class.
  32. /// </summary>
  33. /// <param name="modulus">The modulus.</param>
  34. /// <param name="exponent">The exponent.</param>
  35. internal CryptoPublicKeyRsa(byte[] modulus, byte[] exponent)
  36. {
  37. this._modulus = modulus;
  38. this._exponent = exponent;
  39. }
  40. /// <summary>
  41. /// Loads key specific data.
  42. /// </summary>
  43. /// <param name="data">The data.</param>
  44. public override void Load(IEnumerable<byte> data)
  45. {
  46. MemoryStream ms = null;
  47. try
  48. {
  49. ms = new MemoryStream(data.ToArray());
  50. using (var br = new BinaryReader(ms))
  51. {
  52. var el = (uint)(br.ReadByte() << 24 | br.ReadByte() << 16 | br.ReadByte() << 8 | br.ReadByte());
  53. this._exponent = br.ReadBytes((int)el);
  54. var ml = (uint)(br.ReadByte() << 24 | br.ReadByte() << 16 | br.ReadByte() << 8 | br.ReadByte());
  55. this._modulus = br.ReadBytes((int)ml);
  56. }
  57. }
  58. finally
  59. {
  60. if (ms != null)
  61. {
  62. ms.Dispose();
  63. ms = null;
  64. }
  65. }
  66. }
  67. /// <summary>
  68. /// Verifies the signature.
  69. /// </summary>
  70. /// <param name="hash">The hash.</param>
  71. /// <param name="signature">The signature.</param>
  72. /// <returns>
  73. /// true if signature verified; otherwise false.
  74. /// </returns>
  75. public override bool VerifySignature(IEnumerable<byte> hash, IEnumerable<byte> signature)
  76. {
  77. long i = 0;
  78. long j = 0;
  79. byte[] tmp;
  80. var sig = signature.ToArray();
  81. if (sig[0] == 0 && sig[1] == 0 && sig[2] == 0)
  82. {
  83. long i1 = (sig[i++] << 24) & 0xff000000;
  84. long i2 = (sig[i++] << 16) & 0x00ff0000;
  85. long i3 = (sig[i++] << 8) & 0x0000ff00;
  86. long i4 = (sig[i++]) & 0x000000ff;
  87. j = i1 | i2 | i3 | i4;
  88. i += j;
  89. i1 = (sig[i++] << 24) & 0xff000000;
  90. i2 = (sig[i++] << 16) & 0x00ff0000;
  91. i3 = (sig[i++] << 8) & 0x0000ff00;
  92. i4 = (sig[i++]) & 0x000000ff;
  93. j = i1 | i2 | i3 | i4;
  94. tmp = new byte[j];
  95. Array.Copy(sig, (int)i, tmp, 0, (int)j);
  96. sig = tmp;
  97. }
  98. var sig1 = new RSADigitalSignature(new RSAPublicKey(this._exponent, this._modulus));
  99. return sig1.VerifySignature(hash.ToArray(), sig);
  100. }
  101. /// <summary>
  102. /// Gets key data byte array.
  103. /// </summary>
  104. /// <returns>
  105. /// The data byte array.
  106. /// </returns>
  107. public override IEnumerable<byte> GetBytes()
  108. {
  109. return new RsaPublicKeyData
  110. {
  111. E = this._exponent,
  112. Modulus = this._modulus,
  113. }.GetBytes();
  114. }
  115. private class RsaPublicKeyData : SshData
  116. {
  117. public byte[] Modulus { get; set; }
  118. public byte[] E { get; set; }
  119. protected override void LoadData()
  120. {
  121. }
  122. protected override void SaveData()
  123. {
  124. this.Write("ssh-rsa");
  125. this.WriteBinaryString(this.E);
  126. this.WriteBinaryString(this.Modulus);
  127. }
  128. }
  129. }
  130. }