DtlsReplayWindow.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.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. * </p>
  11. */
  12. internal sealed class DtlsReplayWindow
  13. {
  14. private const long ValidSeqMask = 0x0000FFFFFFFFFFFFL;
  15. private const long WindowSize = 64L;
  16. private long m_latestConfirmedSeq = -1;
  17. private ulong m_bitmap = 0;
  18. /// <summary>Check whether a received record with the given sequence number should be rejected as a duplicate.
  19. /// </summary>
  20. /// <param name="seq">the 48-bit DTLSPlainText.sequence_number field of a received record.</param>
  21. /// <returns>true if the record should be discarded without further processing.</returns>
  22. internal bool ShouldDiscard(long seq)
  23. {
  24. if ((seq & ValidSeqMask) != seq)
  25. return true;
  26. if (seq <= m_latestConfirmedSeq)
  27. {
  28. long diff = m_latestConfirmedSeq - seq;
  29. if (diff >= WindowSize)
  30. return true;
  31. if ((m_bitmap & (1UL << (int)diff)) != 0)
  32. return true;
  33. }
  34. return false;
  35. }
  36. /// <summary>Report that a received record with the given sequence number passed authentication checks.
  37. /// </summary>
  38. /// <param name="seq">the 48-bit DTLSPlainText.sequence_number field of an authenticated record.</param>
  39. internal void ReportAuthenticated(long seq)
  40. {
  41. if ((seq & ValidSeqMask) != seq)
  42. throw new ArgumentException("out of range", "seq");
  43. if (seq <= m_latestConfirmedSeq)
  44. {
  45. long diff = m_latestConfirmedSeq - seq;
  46. if (diff < WindowSize)
  47. {
  48. m_bitmap |= (1UL << (int)diff);
  49. }
  50. }
  51. else
  52. {
  53. long diff = seq - m_latestConfirmedSeq;
  54. if (diff >= WindowSize)
  55. {
  56. m_bitmap = 1;
  57. }
  58. else
  59. {
  60. m_bitmap <<= (int)diff; // for earlier JDKs
  61. m_bitmap |= 1UL;
  62. }
  63. m_latestConfirmedSeq = seq;
  64. }
  65. }
  66. internal void Reset(long seq)
  67. {
  68. if ((seq & ValidSeqMask) != seq)
  69. throw new ArgumentException("out of range", "seq");
  70. // Discard future records unless sequence number > 'seq'
  71. m_latestConfirmedSeq = seq;
  72. m_bitmap = ulong.MaxValue >> (int)System.Math.Max(0, 63 - seq);
  73. }
  74. }
  75. }
  76. #pragma warning restore
  77. #endif