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