handshake_cache_test.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package dtls
  4. import (
  5. "bytes"
  6. "testing"
  7. "github.com/pion/dtls/v2/internal/ciphersuite"
  8. "github.com/pion/dtls/v2/pkg/protocol/handshake"
  9. )
  10. func TestHandshakeCacheSinglePush(t *testing.T) {
  11. for _, test := range []struct {
  12. Name string
  13. Rule []handshakeCachePullRule
  14. Input []handshakeCacheItem
  15. Expected []byte
  16. }{
  17. {
  18. Name: "Single Push",
  19. Input: []handshakeCacheItem{
  20. {0, true, 0, 0, []byte{0x00}},
  21. },
  22. Rule: []handshakeCachePullRule{
  23. {0, 0, true, false},
  24. },
  25. Expected: []byte{0x00},
  26. },
  27. {
  28. Name: "Multi Push",
  29. Input: []handshakeCacheItem{
  30. {0, true, 0, 0, []byte{0x00}},
  31. {1, true, 0, 1, []byte{0x01}},
  32. {2, true, 0, 2, []byte{0x02}},
  33. },
  34. Rule: []handshakeCachePullRule{
  35. {0, 0, true, false},
  36. {1, 0, true, false},
  37. {2, 0, true, false},
  38. },
  39. Expected: []byte{0x00, 0x01, 0x02},
  40. },
  41. {
  42. Name: "Multi Push, Rules set order",
  43. Input: []handshakeCacheItem{
  44. {2, true, 0, 2, []byte{0x02}},
  45. {0, true, 0, 0, []byte{0x00}},
  46. {1, true, 0, 1, []byte{0x01}},
  47. },
  48. Rule: []handshakeCachePullRule{
  49. {0, 0, true, false},
  50. {1, 0, true, false},
  51. {2, 0, true, false},
  52. },
  53. Expected: []byte{0x00, 0x01, 0x02},
  54. },
  55. {
  56. Name: "Multi Push, Dupe Seqnum",
  57. Input: []handshakeCacheItem{
  58. {0, true, 0, 0, []byte{0x00}},
  59. {1, true, 0, 1, []byte{0x01}},
  60. {1, true, 0, 1, []byte{0x01}},
  61. },
  62. Rule: []handshakeCachePullRule{
  63. {0, 0, true, false},
  64. {1, 0, true, false},
  65. },
  66. Expected: []byte{0x00, 0x01},
  67. },
  68. {
  69. Name: "Multi Push, Dupe Seqnum Client/Server",
  70. Input: []handshakeCacheItem{
  71. {0, true, 0, 0, []byte{0x00}},
  72. {1, true, 0, 1, []byte{0x01}},
  73. {1, false, 0, 1, []byte{0x02}},
  74. },
  75. Rule: []handshakeCachePullRule{
  76. {0, 0, true, false},
  77. {1, 0, true, false},
  78. {1, 0, false, false},
  79. },
  80. Expected: []byte{0x00, 0x01, 0x02},
  81. },
  82. {
  83. Name: "Multi Push, Dupe Seqnum with Unique HandshakeType",
  84. Input: []handshakeCacheItem{
  85. {1, true, 0, 0, []byte{0x00}},
  86. {2, true, 0, 1, []byte{0x01}},
  87. {3, false, 0, 0, []byte{0x02}},
  88. },
  89. Rule: []handshakeCachePullRule{
  90. {1, 0, true, false},
  91. {2, 0, true, false},
  92. {3, 0, false, false},
  93. },
  94. Expected: []byte{0x00, 0x01, 0x02},
  95. },
  96. {
  97. Name: "Multi Push, Wrong epoch",
  98. Input: []handshakeCacheItem{
  99. {1, true, 0, 0, []byte{0x00}},
  100. {2, true, 1, 1, []byte{0x01}},
  101. {2, true, 0, 2, []byte{0x11}},
  102. {3, false, 0, 0, []byte{0x02}},
  103. {3, false, 1, 0, []byte{0x12}},
  104. {3, false, 2, 0, []byte{0x12}},
  105. },
  106. Rule: []handshakeCachePullRule{
  107. {1, 0, true, false},
  108. {2, 1, true, false},
  109. {3, 0, false, false},
  110. },
  111. Expected: []byte{0x00, 0x01, 0x02},
  112. },
  113. } {
  114. h := newHandshakeCache()
  115. for _, i := range test.Input {
  116. h.push(i.data, i.epoch, i.messageSequence, i.typ, i.isClient)
  117. }
  118. verifyData := h.pullAndMerge(test.Rule...)
  119. if !bytes.Equal(verifyData, test.Expected) {
  120. t.Errorf("handshakeCache '%s' exp: % 02x actual % 02x", test.Name, test.Expected, verifyData)
  121. }
  122. }
  123. }
  124. func TestHandshakeCacheSessionHash(t *testing.T) {
  125. for _, test := range []struct {
  126. Name string
  127. Rule []handshakeCachePullRule
  128. Input []handshakeCacheItem
  129. Expected []byte
  130. }{
  131. {
  132. Name: "Standard Handshake",
  133. Input: []handshakeCacheItem{
  134. {handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
  135. {handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
  136. {handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
  137. {handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
  138. {handshake.TypeServerHelloDone, false, 0, 4, []byte{0x04}},
  139. {handshake.TypeClientKeyExchange, true, 0, 5, []byte{0x05}},
  140. },
  141. Expected: []byte{0x17, 0xe8, 0x8d, 0xb1, 0x87, 0xaf, 0xd6, 0x2c, 0x16, 0xe5, 0xde, 0xbf, 0x3e, 0x65, 0x27, 0xcd, 0x00, 0x6b, 0xc0, 0x12, 0xbc, 0x90, 0xb5, 0x1a, 0x81, 0x0c, 0xd8, 0x0c, 0x2d, 0x51, 0x1f, 0x43},
  142. },
  143. {
  144. Name: "Handshake With Client Cert Request",
  145. Input: []handshakeCacheItem{
  146. {handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
  147. {handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
  148. {handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
  149. {handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
  150. {handshake.TypeCertificateRequest, false, 0, 4, []byte{0x04}},
  151. {handshake.TypeServerHelloDone, false, 0, 5, []byte{0x05}},
  152. {handshake.TypeClientKeyExchange, true, 0, 6, []byte{0x06}},
  153. },
  154. Expected: []byte{0x57, 0x35, 0x5a, 0xc3, 0x30, 0x3c, 0x14, 0x8f, 0x11, 0xae, 0xf7, 0xcb, 0x17, 0x94, 0x56, 0xb9, 0x23, 0x2c, 0xde, 0x33, 0xa8, 0x18, 0xdf, 0xda, 0x2c, 0x2f, 0xcb, 0x93, 0x25, 0x74, 0x9a, 0x6b},
  155. },
  156. {
  157. Name: "Handshake Ignores after ClientKeyExchange",
  158. Input: []handshakeCacheItem{
  159. {handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
  160. {handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
  161. {handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
  162. {handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
  163. {handshake.TypeCertificateRequest, false, 0, 4, []byte{0x04}},
  164. {handshake.TypeServerHelloDone, false, 0, 5, []byte{0x05}},
  165. {handshake.TypeClientKeyExchange, true, 0, 6, []byte{0x06}},
  166. {handshake.TypeCertificateVerify, true, 0, 7, []byte{0x07}},
  167. {handshake.TypeFinished, true, 1, 7, []byte{0x08}},
  168. {handshake.TypeFinished, false, 1, 7, []byte{0x09}},
  169. },
  170. Expected: []byte{0x57, 0x35, 0x5a, 0xc3, 0x30, 0x3c, 0x14, 0x8f, 0x11, 0xae, 0xf7, 0xcb, 0x17, 0x94, 0x56, 0xb9, 0x23, 0x2c, 0xde, 0x33, 0xa8, 0x18, 0xdf, 0xda, 0x2c, 0x2f, 0xcb, 0x93, 0x25, 0x74, 0x9a, 0x6b},
  171. },
  172. {
  173. Name: "Handshake Ignores wrong epoch",
  174. Input: []handshakeCacheItem{
  175. {handshake.TypeClientHello, true, 0, 0, []byte{0x00}},
  176. {handshake.TypeServerHello, false, 0, 1, []byte{0x01}},
  177. {handshake.TypeCertificate, false, 0, 2, []byte{0x02}},
  178. {handshake.TypeServerKeyExchange, false, 0, 3, []byte{0x03}},
  179. {handshake.TypeCertificateRequest, false, 0, 4, []byte{0x04}},
  180. {handshake.TypeServerHelloDone, false, 0, 5, []byte{0x05}},
  181. {handshake.TypeClientKeyExchange, true, 0, 6, []byte{0x06}},
  182. {handshake.TypeCertificateVerify, true, 0, 7, []byte{0x07}},
  183. {handshake.TypeFinished, true, 0, 7, []byte{0xf0}},
  184. {handshake.TypeFinished, false, 0, 7, []byte{0xf1}},
  185. {handshake.TypeFinished, true, 1, 7, []byte{0x08}},
  186. {handshake.TypeFinished, false, 1, 7, []byte{0x09}},
  187. {handshake.TypeFinished, true, 0, 7, []byte{0xf0}},
  188. {handshake.TypeFinished, false, 0, 7, []byte{0xf1}},
  189. },
  190. Expected: []byte{0x57, 0x35, 0x5a, 0xc3, 0x30, 0x3c, 0x14, 0x8f, 0x11, 0xae, 0xf7, 0xcb, 0x17, 0x94, 0x56, 0xb9, 0x23, 0x2c, 0xde, 0x33, 0xa8, 0x18, 0xdf, 0xda, 0x2c, 0x2f, 0xcb, 0x93, 0x25, 0x74, 0x9a, 0x6b},
  191. },
  192. } {
  193. h := newHandshakeCache()
  194. for _, i := range test.Input {
  195. h.push(i.data, i.epoch, i.messageSequence, i.typ, i.isClient)
  196. }
  197. cipherSuite := ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{}
  198. verifyData, err := h.sessionHash(cipherSuite.HashFunc(), 0)
  199. if err != nil {
  200. t.Error(err)
  201. }
  202. if !bytes.Equal(verifyData, test.Expected) {
  203. t.Errorf("handshakeCacheSesssionHassh '%s' exp: % 02x actual % 02x", test.Name, test.Expected, verifyData)
  204. }
  205. }
  206. }