request_test.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. package fp_test
  2. import (
  3. "testing"
  4. fp "github.com/cloudflare/mitmengine/fputil"
  5. "github.com/cloudflare/mitmengine/testutil"
  6. )
  7. var (
  8. emptyVersionSig = fp.VersionSignature{}
  9. emptyIntSig = fp.IntSignature{fp.IntList{}, &fp.IntSet{}, &fp.IntSet{}, &fp.IntSet{}, &fp.IntSet{}}
  10. emptyStringSig = fp.StringSignature{
  11. OrderedList: fp.StringList{},
  12. OptionalSet: make(fp.StringSet),
  13. UnlikelySet: make(fp.StringSet),
  14. ExcludedSet: make(fp.StringSet),
  15. RequiredSet: make(fp.StringSet),
  16. }
  17. anyStringSig = fp.StringSignature{
  18. OrderedList: nil,
  19. OptionalSet: nil,
  20. UnlikelySet: make(fp.StringSet),
  21. ExcludedSet: make(fp.StringSet),
  22. RequiredSet: make(fp.StringSet),
  23. }
  24. )
  25. func TestNewRequestFingerprint(t *testing.T) {
  26. var tests = []struct {
  27. in string
  28. out fp.RequestFingerprint
  29. }{
  30. {"::::::", fp.RequestFingerprint{}},
  31. }
  32. for _, test := range tests {
  33. fingerprint, err := fp.NewRequestFingerprint(test.in)
  34. testutil.Ok(t, err)
  35. testutil.Equals(t, test.out, fingerprint)
  36. }
  37. }
  38. func TestRequestFingerprintString(t *testing.T) {
  39. var tests = []struct {
  40. in fp.RequestFingerprint
  41. out string
  42. }{
  43. {fp.RequestFingerprint{}, "::::::"},
  44. }
  45. for _, test := range tests {
  46. testutil.Equals(t, test.out, test.in.String())
  47. }
  48. }
  49. func TestNewRequestSignature(t *testing.T) {
  50. var tests = []struct {
  51. str string
  52. sig fp.RequestSignature
  53. }{
  54. {"::::::", fp.RequestSignature{
  55. Version: emptyVersionSig,
  56. Cipher: emptyIntSig,
  57. Extension: emptyIntSig,
  58. Curve: emptyIntSig,
  59. EcPointFmt: emptyIntSig,
  60. Header: emptyStringSig,
  61. Quirk: emptyStringSig,
  62. }},
  63. }
  64. for _, test := range tests {
  65. sig, err := fp.NewRequestSignature(test.str)
  66. testutil.Ok(t, err)
  67. testutil.Equals(t, test.sig, sig)
  68. }
  69. }
  70. func TestRequestSignatureString(t *testing.T) {
  71. var tests = []struct {
  72. in fp.RequestSignature
  73. out string
  74. }{
  75. {fp.RequestSignature{
  76. Version: emptyVersionSig,
  77. Cipher: emptyIntSig,
  78. Extension: emptyIntSig,
  79. Curve: emptyIntSig,
  80. EcPointFmt: emptyIntSig,
  81. Header: emptyStringSig,
  82. Quirk: emptyStringSig,
  83. }, "::::::"},
  84. }
  85. for _, test := range tests {
  86. testutil.Equals(t, test.out, test.in.String())
  87. }
  88. }
  89. func TestRequestSignatureMerge(t *testing.T) {
  90. var tests = []struct {
  91. in1 string
  92. in2 string
  93. out string
  94. }{
  95. {"::::::", "::::::", "::::::"},
  96. {":*:*:*:*:*:*", ":*:*:*:*:*:*", ":*:*:*:*:*:*"},
  97. }
  98. for _, test := range tests {
  99. signature1, err := fp.NewRequestSignature(test.in1)
  100. testutil.Equals(t, nil, err)
  101. signature2, err := fp.NewRequestSignature(test.in2)
  102. testutil.Equals(t, nil, err)
  103. testutil.Equals(t, test.out, signature1.Merge(signature2).String())
  104. }
  105. }
  106. // todo fill this function out
  107. func TestVersionSignatureMerge(t *testing.T) {
  108. var tests = []struct {
  109. in1 string
  110. in2 string
  111. out string
  112. }{}
  113. for _, test := range tests {
  114. signature1, err := fp.NewIntSignature(test.in1)
  115. testutil.Ok(t, err)
  116. signature2, err := fp.NewIntSignature(test.in2)
  117. testutil.Ok(t, err)
  118. testutil.Equals(t, test.out, signature1.Merge(signature2).String())
  119. }
  120. }
  121. func TestIntSignatureMerge(t *testing.T) {
  122. var tests = []struct {
  123. in1 string
  124. in2 string
  125. out string
  126. }{
  127. {"", "", ""},
  128. {"*", "1", "*"},
  129. {"*", "1,^2", "*"},
  130. {"*^2", "1,^2", "*^2"},
  131. {"1,2", "2,1", "~1,2"},
  132. {"1,2", "1,2,3", "1,2,?3"},
  133. {"1,4", "2,3", "?1,?4,?2,?3"},
  134. {"1,2", "3,2,1", "~1,2,?3"},
  135. {"1,2", "3,1,2", "?3,1,2"},
  136. }
  137. for _, test := range tests {
  138. signature1, err := fp.NewIntSignature(test.in1)
  139. testutil.Ok(t, err)
  140. signature2, err := fp.NewIntSignature(test.in2)
  141. testutil.Ok(t, err)
  142. testutil.Equals(t, test.out, signature1.Merge(signature2).String())
  143. }
  144. }
  145. func TestStringSignatureMerge(t *testing.T) {
  146. var tests = []struct {
  147. in1 string
  148. in2 string
  149. out string
  150. }{
  151. {"", "", ""},
  152. {"*", "1", "*"},
  153. {"*", "1,^2", "*"},
  154. {"*^2", "1,^2", "*^2"},
  155. {"1,2", "2,1", "~1,2"},
  156. {"1,2", "1,2,3", "1,2,?3"},
  157. {"1,4", "2,3", "?1,?4,?2,?3"},
  158. {"1,2", "3,2,1", "~1,2,?3"},
  159. {"1,2", "3,1,2", "?3,1,2"},
  160. }
  161. for _, test := range tests {
  162. signature1, err := fp.NewStringSignature(test.in1)
  163. testutil.Ok(t, err)
  164. signature2, err := fp.NewStringSignature(test.in2)
  165. testutil.Ok(t, err)
  166. testutil.Equals(t, test.out, signature1.Merge(signature2).String())
  167. }
  168. }
  169. func TestRequestSignatureMatch(t *testing.T) {
  170. var tests = []struct {
  171. in1 string
  172. in2 string
  173. out fp.Match
  174. }{
  175. {"::::::", "::::::", fp.MatchPossible},
  176. {":*:*:*:*:*:*", "::::::", fp.MatchPossible},
  177. }
  178. for _, test := range tests {
  179. signature, err := fp.NewRequestSignature(test.in1)
  180. testutil.Ok(t, err)
  181. fingerprint, err := fp.NewRequestFingerprint(test.in2)
  182. testutil.Ok(t, err)
  183. signatureMatch, _ := signature.Match(fingerprint)
  184. testutil.Equals(t, signatureMatch, test.out)
  185. }
  186. }
  187. func TestVersionSignatureMatch(t *testing.T) {
  188. var tests = []struct {
  189. in1 string
  190. in2 string
  191. out fp.Match
  192. }{
  193. {"", "303", fp.MatchPossible}, // match anything
  194. {",,", "303", fp.MatchPossible}, // long version, match anything
  195. {"0200", "200", fp.MatchPossible},
  196. {"2", "200", fp.MatchPossible},
  197. {"200,200,302", "301", fp.MatchPossible},
  198. {"200,302,302", "301", fp.MatchUnlikely},
  199. {"302,302,302", "301", fp.MatchImpossible},
  200. {"200,200,301", "302", fp.MatchImpossible},
  201. }
  202. for _, test := range tests {
  203. signature, err := fp.NewVersionSignature(test.in1)
  204. testutil.Ok(t, err)
  205. fingerprint, err := fp.NewVersion(test.in2)
  206. testutil.Ok(t, err)
  207. testutil.Equals(t, signature.Match(fingerprint), test.out)
  208. }
  209. }
  210. func TestIntSignatureMatch(t *testing.T) {
  211. var tests = []struct {
  212. in1 string
  213. in2 string
  214. out fp.Match
  215. }{
  216. {"", "", fp.MatchPossible},
  217. {"*", "1", fp.MatchPossible},
  218. {"*", "1,2", fp.MatchPossible},
  219. {"*1,^2", "1,2", fp.MatchImpossible},
  220. {"*1,^2", "1", fp.MatchPossible},
  221. {"~1,2", "2,1", fp.MatchPossible},
  222. {"~1,^2", "1,2", fp.MatchImpossible},
  223. {"1,2", "2,1", fp.MatchImpossible},
  224. {"1,?2", "2,1", fp.MatchImpossible},
  225. {"~1,?2", "2,1", fp.MatchPossible},
  226. {"1,2", "1,2,3", fp.MatchImpossible},
  227. {"1,2,?3", "1,2,3", fp.MatchPossible},
  228. {"*1,2", "1,2,3", fp.MatchPossible},
  229. {"*1,2", "3,2,1", fp.MatchPossible},
  230. {"?1,2,?3", "1,2", fp.MatchPossible},
  231. {"?1,2,?3", "2,3", fp.MatchPossible},
  232. {"?1,2,?3", "1,3", fp.MatchImpossible},
  233. }
  234. for _, test := range tests {
  235. signature, err := fp.NewIntSignature(test.in1)
  236. testutil.Ok(t, err)
  237. fingerprint, err := fp.NewIntList(test.in2)
  238. testutil.Ok(t, err)
  239. match, _ := signature.Match(fingerprint)
  240. testutil.Equals(t, test.out, match)
  241. }
  242. }
  243. func TestStringSignatureMatch(t *testing.T) {
  244. var tests = []struct {
  245. in1 string
  246. in2 string
  247. out fp.Match
  248. }{
  249. {"", "", fp.MatchPossible},
  250. {"*", "1", fp.MatchPossible},
  251. {"*", "1,2", fp.MatchPossible},
  252. {"*1,^2", "1,2", fp.MatchImpossible},
  253. {"*1,^2", "1", fp.MatchPossible},
  254. {"~1,2", "2,1", fp.MatchPossible},
  255. {"~1,^2", "1,2", fp.MatchImpossible},
  256. {"1,2", "2,1", fp.MatchImpossible},
  257. {"1,?2", "2,1", fp.MatchImpossible},
  258. {"~1,?2", "2,1", fp.MatchPossible},
  259. {"1,2", "1,2,3", fp.MatchImpossible},
  260. {"1,2,?3", "1,2,3", fp.MatchPossible},
  261. {"*1,2", "1,2,3", fp.MatchPossible},
  262. {"*1,2", "3,2,1", fp.MatchPossible},
  263. {"?1,2,?3", "1,2", fp.MatchPossible},
  264. {"?1,2,?3", "2,3", fp.MatchPossible},
  265. {"?1,2,?3", "1,3", fp.MatchImpossible},
  266. {"!1", "1", fp.MatchUnlikely},
  267. {"*!1", "1", fp.MatchUnlikely},
  268. {"!1,2,?3", "1,2", fp.MatchUnlikely},
  269. }
  270. for _, test := range tests {
  271. signature1, err := fp.NewStringSignature(test.in1)
  272. testutil.Ok(t, err)
  273. signature2, err := fp.NewStringList(test.in2)
  274. testutil.Ok(t, err)
  275. testutil.Equals(t, test.out, signature1.Match(signature2))
  276. }
  277. }
  278. func TestGrade(t *testing.T) {
  279. requestFingerprint := "0303:1301,1302,1303,c02b,c02f,c02c,c030,cca9,cca8,c013,c014,9c,9d,2f,35,0a:~00,17,ff01,0a,0b,23,10,05,0d,12,33,2d,2b,1b,15:1d,17,18:00:*:grease"
  280. requestSignature, err := fp.NewRequestSignature(requestFingerprint)
  281. if err != nil {
  282. t.Fatal("request signature could not be parsed")
  283. }
  284. grade := requestSignature.Grade()
  285. testutil.Equals(t, fp.GradeA, grade)
  286. }