DtlsReplayWindow.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Tls
  5. {
  6. /**
  7. * RFC 4347 4.1.2.5 Anti-replay
  8. * <p/>
  9. * Support fast rejection of duplicate records by maintaining a sliding receive window
  10. */
  11. internal class DtlsReplayWindow
  12. {
  13. private const long VALID_SEQ_MASK = 0x0000FFFFFFFFFFFFL;
  14. private const long WINDOW_SIZE = 64L;
  15. private long mLatestConfirmedSeq = -1;
  16. private long mBitmap = 0;
  17. /**
  18. * Check whether a received record with the given sequence number should be rejected as a duplicate.
  19. *
  20. * @param seq the 48-bit DTLSPlainText.sequence_number field of a received record.
  21. * @return true if the record should be discarded without further processing.
  22. */
  23. internal bool ShouldDiscard(long seq)
  24. {
  25. if ((seq & VALID_SEQ_MASK) != seq)
  26. return true;
  27. if (seq <= mLatestConfirmedSeq)
  28. {
  29. long diff = mLatestConfirmedSeq - seq;
  30. if (diff >= WINDOW_SIZE)
  31. return true;
  32. if ((mBitmap & (1L << (int)diff)) != 0)
  33. return true;
  34. }
  35. return false;
  36. }
  37. /**
  38. * Report that a received record with the given sequence number passed authentication checks.
  39. *
  40. * @param seq the 48-bit DTLSPlainText.sequence_number field of an authenticated record.
  41. */
  42. internal void ReportAuthenticated(long seq)
  43. {
  44. if ((seq & VALID_SEQ_MASK) != seq)
  45. throw new ArgumentException("out of range", "seq");
  46. if (seq <= mLatestConfirmedSeq)
  47. {
  48. long diff = mLatestConfirmedSeq - seq;
  49. if (diff < WINDOW_SIZE)
  50. {
  51. mBitmap |= (1L << (int)diff);
  52. }
  53. }
  54. else
  55. {
  56. long diff = seq - mLatestConfirmedSeq;
  57. if (diff >= WINDOW_SIZE)
  58. {
  59. mBitmap = 1;
  60. }
  61. else
  62. {
  63. mBitmap <<= (int)diff;
  64. mBitmap |= 1;
  65. }
  66. mLatestConfirmedSeq = seq;
  67. }
  68. }
  69. /**
  70. * When a new epoch begins, sequence numbers begin again at 0
  71. */
  72. internal void Reset()
  73. {
  74. mLatestConfirmedSeq = -1;
  75. mBitmap = 0;
  76. }
  77. }
  78. }
  79. #pragma warning restore
  80. #endif