CombinedHash.cs 3.8 KB

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