DtlsVerifier.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
  8. {
  9. public class DtlsVerifier
  10. {
  11. private static TlsMac CreateCookieMac(TlsCrypto crypto)
  12. {
  13. TlsMac mac = crypto.CreateHmac(MacAlgorithm.hmac_sha256);
  14. byte[] secret = new byte[mac.MacLength];
  15. crypto.SecureRandom.NextBytes(secret);
  16. mac.SetKey(secret, 0, secret.Length);
  17. return mac;
  18. }
  19. private readonly TlsMac m_cookieMac;
  20. private readonly TlsMacSink m_cookieMacSink;
  21. public DtlsVerifier(TlsCrypto crypto)
  22. {
  23. this.m_cookieMac = CreateCookieMac(crypto);
  24. this.m_cookieMacSink = new TlsMacSink(m_cookieMac);
  25. }
  26. public virtual DtlsRequest VerifyRequest(byte[] clientID, byte[] data, int dataOff, int dataLen,
  27. DatagramSender sender)
  28. {
  29. lock (this)
  30. {
  31. bool resetCookieMac = true;
  32. try
  33. {
  34. m_cookieMac.Update(clientID, 0, clientID.Length);
  35. DtlsRequest request = DtlsReliableHandshake.ReadClientRequest(data, dataOff, dataLen,
  36. m_cookieMacSink);
  37. if (null != request)
  38. {
  39. byte[] expectedCookie = m_cookieMac.CalculateMac();
  40. resetCookieMac = false;
  41. // TODO Consider stricter HelloVerifyRequest protocol
  42. //switch (request.MessageSeq)
  43. //{
  44. //case 0:
  45. //{
  46. // DtlsReliableHandshake.SendHelloVerifyRequest(sender, request.RecordSeq, expectedCookie);
  47. // break;
  48. //}
  49. //case 1:
  50. //{
  51. // if (Arrays.ConstantTimeAreEqual(expectedCookie, request.ClientHello.Cookie))
  52. // return request;
  53. // break;
  54. //}
  55. //}
  56. if (Arrays.ConstantTimeAreEqual(expectedCookie, request.ClientHello.Cookie))
  57. return request;
  58. DtlsReliableHandshake.SendHelloVerifyRequest(sender, request.RecordSeq, expectedCookie);
  59. }
  60. }
  61. catch (IOException)
  62. {
  63. // Ignore
  64. }
  65. finally
  66. {
  67. if (resetCookieMac)
  68. {
  69. m_cookieMac.Reset();
  70. }
  71. }
  72. return null;
  73. }
  74. }
  75. }
  76. }
  77. #pragma warning restore
  78. #endif