X931Signer.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace BestHTTP.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. public const int TRAILER_IMPLICIT = 0xBC;
  24. public const int TRAILER_RIPEMD160 = 0x31CC;
  25. public const int TRAILER_RIPEMD128 = 0x32CC;
  26. public const int TRAILER_SHA1 = 0x33CC;
  27. public const int TRAILER_SHA256 = 0x34CC;
  28. public const int TRAILER_SHA512 = 0x35CC;
  29. public const int TRAILER_SHA384 = 0x36CC;
  30. public const int TRAILER_WHIRLPOOL = 0x37CC;
  31. public const int TRAILER_SHA224 = 0x38CC;
  32. private IDigest digest;
  33. private IAsymmetricBlockCipher cipher;
  34. private RsaKeyParameters kParam;
  35. private int trailer;
  36. private int keyBits;
  37. private byte[] block;
  38. /**
  39. * Generate a signer with either implicit or explicit trailers for X9.31.
  40. *
  41. * @param cipher base cipher to use for signature creation/verification
  42. * @param digest digest to use.
  43. * @param implicit whether or not the trailer is implicit or gives the hash.
  44. */
  45. public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
  46. {
  47. this.cipher = cipher;
  48. this.digest = digest;
  49. if (isImplicit)
  50. {
  51. trailer = IsoTrailers.TRAILER_IMPLICIT;
  52. }
  53. else if (IsoTrailers.NoTrailerAvailable(digest))
  54. {
  55. throw new ArgumentException("no valid trailer", "digest");
  56. }
  57. else
  58. {
  59. trailer = IsoTrailers.GetTrailer(digest);
  60. }
  61. }
  62. public virtual string AlgorithmName
  63. {
  64. get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; }
  65. }
  66. /**
  67. * Constructor for a signer with an explicit digest trailer.
  68. *
  69. * @param cipher cipher to use.
  70. * @param digest digest to sign with.
  71. */
  72. public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
  73. : this(cipher, digest, false)
  74. {
  75. }
  76. public virtual void Init(bool forSigning, ICipherParameters parameters)
  77. {
  78. kParam = (RsaKeyParameters)parameters;
  79. cipher.Init(forSigning, kParam);
  80. keyBits = kParam.Modulus.BitLength;
  81. block = new byte[(keyBits + 7) / 8];
  82. Reset();
  83. }
  84. /// <summary> clear possible sensitive data</summary>
  85. private void ClearBlock(byte[] block)
  86. {
  87. Array.Clear(block, 0, block.Length);
  88. }
  89. /**
  90. * update the internal digest with the byte b
  91. */
  92. public virtual void Update(byte b)
  93. {
  94. digest.Update(b);
  95. }
  96. /**
  97. * update the internal digest with the byte array in
  98. */
  99. public virtual void BlockUpdate(byte[] input, int off, int len)
  100. {
  101. digest.BlockUpdate(input, off, len);
  102. }
  103. /**
  104. * reset the internal state
  105. */
  106. public virtual void Reset()
  107. {
  108. digest.Reset();
  109. }
  110. /**
  111. * generate a signature for the loaded message using the key we were
  112. * initialised with.
  113. */
  114. public virtual byte[] GenerateSignature()
  115. {
  116. CreateSignatureBlock();
  117. BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
  118. ClearBlock(block);
  119. t = t.Min(kParam.Modulus.Subtract(t));
  120. int size = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
  121. return BigIntegers.AsUnsignedByteArray(size, t);
  122. }
  123. private void CreateSignatureBlock()
  124. {
  125. int digSize = digest.GetDigestSize();
  126. int delta;
  127. if (trailer == IsoTrailers.TRAILER_IMPLICIT)
  128. {
  129. delta = block.Length - digSize - 1;
  130. digest.DoFinal(block, delta);
  131. block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT;
  132. }
  133. else
  134. {
  135. delta = block.Length - digSize - 2;
  136. digest.DoFinal(block, delta);
  137. block[block.Length - 2] = (byte)(trailer >> 8);
  138. block[block.Length - 1] = (byte)trailer;
  139. }
  140. block[0] = 0x6b;
  141. for (int i = delta - 2; i != 0; i--)
  142. {
  143. block[i] = (byte)0xbb;
  144. }
  145. block[delta - 1] = (byte)0xba;
  146. }
  147. /**
  148. * return true if the signature represents a ISO9796-2 signature
  149. * for the passed in message.
  150. */
  151. public virtual bool VerifySignature(byte[] signature)
  152. {
  153. try
  154. {
  155. block = cipher.ProcessBlock(signature, 0, signature.Length);
  156. }
  157. catch (Exception)
  158. {
  159. return false;
  160. }
  161. BigInteger t = new BigInteger(1, block);
  162. BigInteger f;
  163. if ((t.IntValue & 15) == 12)
  164. {
  165. f = t;
  166. }
  167. else
  168. {
  169. t = kParam.Modulus.Subtract(t);
  170. if ((t.IntValue & 15) == 12)
  171. {
  172. f = t;
  173. }
  174. else
  175. {
  176. return false;
  177. }
  178. }
  179. CreateSignatureBlock();
  180. byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
  181. bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
  182. ClearBlock(block);
  183. ClearBlock(fBlock);
  184. return rv;
  185. }
  186. }
  187. }
  188. #pragma warning restore
  189. #endif