X931Signer.cs 6.7 KB

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