X931Signer.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Zlib;
  8. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
  9. {
  10. /**
  11. * X9.31-1998 - signing using a hash.
  12. * <p>
  13. * The message digest hash, H, is encapsulated to form a byte string as follows
  14. * </p>
  15. * <pre>
  16. * EB = 06 || PS || 0xBA || H || TRAILER
  17. * </pre>
  18. * where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number† for the digest. The byte string, EB, is converted to an integer value, the message representative, f.
  19. */
  20. public class X931Signer
  21. : ISigner
  22. {
  23. private IDigest digest;
  24. private IAsymmetricBlockCipher cipher;
  25. private RsaKeyParameters kParam;
  26. private int trailer;
  27. private int keyBits;
  28. private byte[] block;
  29. /**
  30. * Generate a signer with either implicit or explicit trailers for X9.31.
  31. *
  32. * @param cipher base cipher to use for signature creation/verification
  33. * @param digest digest to use.
  34. * @param implicit whether or not the trailer is implicit or gives the hash.
  35. */
  36. public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
  37. {
  38. this.cipher = cipher;
  39. this.digest = digest;
  40. if (isImplicit)
  41. {
  42. trailer = IsoTrailers.TRAILER_IMPLICIT;
  43. }
  44. else if (IsoTrailers.NoTrailerAvailable(digest))
  45. {
  46. throw new ArgumentException("no valid trailer", "digest");
  47. }
  48. else
  49. {
  50. trailer = IsoTrailers.GetTrailer(digest);
  51. }
  52. }
  53. public virtual string AlgorithmName
  54. {
  55. get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; }
  56. }
  57. /**
  58. * Constructor for a signer with an explicit digest trailer.
  59. *
  60. * @param cipher cipher to use.
  61. * @param digest digest to sign with.
  62. */
  63. public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
  64. : this(cipher, digest, false)
  65. {
  66. }
  67. public virtual void Init(bool forSigning, ICipherParameters parameters)
  68. {
  69. kParam = (RsaKeyParameters)parameters;
  70. cipher.Init(forSigning, kParam);
  71. keyBits = kParam.Modulus.BitLength;
  72. block = new byte[(keyBits + 7) / 8];
  73. Reset();
  74. }
  75. public virtual void Update(byte b)
  76. {
  77. digest.Update(b);
  78. }
  79. public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
  80. {
  81. digest.BlockUpdate(input, inOff, inLen);
  82. }
  83. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  84. public virtual void BlockUpdate(ReadOnlySpan<byte> input)
  85. {
  86. digest.BlockUpdate(input);
  87. }
  88. #endif
  89. public virtual void Reset()
  90. {
  91. digest.Reset();
  92. }
  93. public virtual byte[] GenerateSignature()
  94. {
  95. CreateSignatureBlock();
  96. BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
  97. Arrays.Fill(block, 0x00);
  98. t = t.Min(kParam.Modulus.Subtract(t));
  99. int size = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
  100. return BigIntegers.AsUnsignedByteArray(size, t);
  101. }
  102. private void CreateSignatureBlock()
  103. {
  104. int digSize = digest.GetDigestSize();
  105. int delta;
  106. if (trailer == IsoTrailers.TRAILER_IMPLICIT)
  107. {
  108. delta = block.Length - digSize - 1;
  109. digest.DoFinal(block, delta);
  110. block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT;
  111. }
  112. else
  113. {
  114. delta = block.Length - digSize - 2;
  115. digest.DoFinal(block, delta);
  116. block[block.Length - 2] = (byte)(trailer >> 8);
  117. block[block.Length - 1] = (byte)trailer;
  118. }
  119. block[0] = 0x6b;
  120. for (int i = delta - 2; i != 0; i--)
  121. {
  122. block[i] = (byte)0xbb;
  123. }
  124. block[delta - 1] = (byte)0xba;
  125. }
  126. public virtual bool VerifySignature(byte[] signature)
  127. {
  128. try
  129. {
  130. block = cipher.ProcessBlock(signature, 0, signature.Length);
  131. }
  132. catch (Exception)
  133. {
  134. return false;
  135. }
  136. BigInteger t = new BigInteger(1, block);
  137. BigInteger f;
  138. if ((t.IntValue & 15) == 12)
  139. {
  140. f = t;
  141. }
  142. else
  143. {
  144. t = kParam.Modulus.Subtract(t);
  145. if ((t.IntValue & 15) == 12)
  146. {
  147. f = t;
  148. }
  149. else
  150. {
  151. return false;
  152. }
  153. }
  154. CreateSignatureBlock();
  155. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  156. int fBlockSize = block.Length;
  157. Span<byte> fBlock = fBlockSize <= 512
  158. ? stackalloc byte[fBlockSize]
  159. : new byte[fBlockSize];
  160. BigIntegers.AsUnsignedByteArray(f, fBlock);
  161. #else
  162. byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
  163. #endif
  164. bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
  165. Arrays.Fill(block, 0x00);
  166. Arrays.Fill<byte>(fBlock, 0x00);
  167. return rv;
  168. }
  169. }
  170. }
  171. #pragma warning restore
  172. #endif