CombinedHash.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  5. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  6. {
  7. /**
  8. * A combined hash, which implements md5(m) || sha1(m).
  9. */
  10. internal class CombinedHash
  11. : TlsHandshakeHash
  12. {
  13. protected TlsContext mContext;
  14. protected IDigest mMd5;
  15. protected IDigest mSha1;
  16. internal CombinedHash()
  17. {
  18. this.mMd5 = TlsUtilities.CreateHash(HashAlgorithm.md5);
  19. this.mSha1 = TlsUtilities.CreateHash(HashAlgorithm.sha1);
  20. }
  21. internal CombinedHash(CombinedHash t)
  22. {
  23. this.mContext = t.mContext;
  24. this.mMd5 = TlsUtilities.CloneHash(HashAlgorithm.md5, t.mMd5);
  25. this.mSha1 = TlsUtilities.CloneHash(HashAlgorithm.sha1, t.mSha1);
  26. }
  27. public virtual void Init(TlsContext context)
  28. {
  29. this.mContext = context;
  30. }
  31. public virtual TlsHandshakeHash NotifyPrfDetermined()
  32. {
  33. return this;
  34. }
  35. public virtual void TrackHashAlgorithm(byte hashAlgorithm)
  36. {
  37. throw new InvalidOperationException("CombinedHash only supports calculating the legacy PRF for handshake hash");
  38. }
  39. public virtual void SealHashAlgorithms()
  40. {
  41. }
  42. public virtual TlsHandshakeHash StopTracking()
  43. {
  44. return new CombinedHash(this);
  45. }
  46. public virtual IDigest ForkPrfHash()
  47. {
  48. return new CombinedHash(this);
  49. }
  50. public virtual byte[] GetFinalHash(byte hashAlgorithm)
  51. {
  52. throw new InvalidOperationException("CombinedHash doesn't support multiple hashes");
  53. }
  54. public virtual string AlgorithmName
  55. {
  56. get { return mMd5.AlgorithmName + " and " + mSha1.AlgorithmName; }
  57. }
  58. public virtual int GetByteLength()
  59. {
  60. return System.Math.Max(mMd5.GetByteLength(), mSha1.GetByteLength());
  61. }
  62. public virtual int GetDigestSize()
  63. {
  64. return mMd5.GetDigestSize() + mSha1.GetDigestSize();
  65. }
  66. public virtual void Update(byte input)
  67. {
  68. mMd5.Update(input);
  69. mSha1.Update(input);
  70. }
  71. /**
  72. * @see org.bouncycastle.crypto.Digest#update(byte[], int, int)
  73. */
  74. public virtual void BlockUpdate(byte[] input, int inOff, int len)
  75. {
  76. mMd5.BlockUpdate(input, inOff, len);
  77. mSha1.BlockUpdate(input, inOff, len);
  78. }
  79. /**
  80. * @see org.bouncycastle.crypto.Digest#doFinal(byte[], int)
  81. */
  82. public virtual int DoFinal(byte[] output, int outOff)
  83. {
  84. if (mContext != null && TlsUtilities.IsSsl(mContext))
  85. {
  86. Ssl3Complete(mMd5, Ssl3Mac.IPAD, Ssl3Mac.OPAD, 48);
  87. Ssl3Complete(mSha1, Ssl3Mac.IPAD, Ssl3Mac.OPAD, 40);
  88. }
  89. int i1 = mMd5.DoFinal(output, outOff);
  90. int i2 = mSha1.DoFinal(output, outOff + i1);
  91. return i1 + i2;
  92. }
  93. /**
  94. * @see org.bouncycastle.crypto.Digest#reset()
  95. */
  96. public virtual void Reset()
  97. {
  98. mMd5.Reset();
  99. mSha1.Reset();
  100. }
  101. protected virtual void Ssl3Complete(IDigest d, byte[] ipad, byte[] opad, int padLength)
  102. {
  103. byte[] master_secret = mContext.SecurityParameters.masterSecret;
  104. d.BlockUpdate(master_secret, 0, master_secret.Length);
  105. d.BlockUpdate(ipad, 0, padLength);
  106. byte[] tmp = DigestUtilities.DoFinal(d);
  107. d.BlockUpdate(master_secret, 0, master_secret.Length);
  108. d.BlockUpdate(opad, 0, padLength);
  109. d.BlockUpdate(tmp, 0, tmp.Length);
  110. }
  111. }
  112. }
  113. #pragma warning restore
  114. #endif