protocol_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package aerotun
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "testing"
  7. )
  8. const testPSK = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
  9. func testProtocol(t *testing.T) *protocolState {
  10. t.Helper()
  11. p, err := newProtocol(testPSK)
  12. if err != nil {
  13. t.Fatal(err)
  14. }
  15. return p
  16. }
  17. func testSeal(t *testing.T, p *protocolState, flags byte, b []byte, target sessionID) []byte {
  18. t.Helper()
  19. if flags != 0 && flags != FlagCompressedLZ4 && b == nil {
  20. b = []byte{5, 140}
  21. } // 1420-byte MTU advertisement
  22. out, err := p.seal(flags, b, target)
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. return out
  27. }
  28. func establish(t *testing.T, a, b *protocolState) {
  29. t.Helper()
  30. hello := testSeal(t, a, flagHello, nil, zeroSession)
  31. _, _, sender, _, err := b.open(hello)
  32. if err != nil {
  33. t.Fatal(err)
  34. }
  35. ack := testSeal(t, b, flagAck, nil, sender)
  36. _, _, sender, _, err = a.open(ack)
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. confirm := testSeal(t, a, flagConfirm, nil, sender)
  41. if _, _, _, _, err = b.open(confirm); err != nil {
  42. t.Fatal(err)
  43. }
  44. }
  45. func TestProtocolAuthenticationReplayAndRestart(t *testing.T) {
  46. a, b := testProtocol(t), testProtocol(t)
  47. establish(t, a, b)
  48. forward := testSeal(t, a, 0, []byte("forward"), zeroSession)
  49. reverse := testSeal(t, b, 0, []byte("reverse"), zeroSession)
  50. if bytes.Equal(forward[4:44], reverse[4:44]) {
  51. t.Fatal("directions reuse nonce/key context")
  52. }
  53. bad := append([]byte(nil), forward...)
  54. binary.BigEndian.PutUint64(bad[36:44], 1<<60)
  55. if _, _, _, _, err := b.open(bad); err == nil {
  56. t.Fatal("tampered counter authenticated")
  57. }
  58. got, _, _, _, err := b.open(forward)
  59. if err != nil || string(got) != "forward" {
  60. t.Fatalf("valid data rejected after forgery: %q %v", got, err)
  61. }
  62. if _, _, _, _, err = b.open(forward); !errors.Is(err, errReplay) {
  63. t.Fatalf("duplicate accepted: %v", err)
  64. }
  65. if _, _, _, _, err = a.open(forward); err == nil {
  66. t.Fatal("reflected data accepted")
  67. }
  68. if got, _, _, _, err = a.open(reverse); err != nil || string(got) != "reverse" {
  69. t.Fatal(err)
  70. }
  71. oldAck := testSeal(t, a, flagAck, nil, b.local)
  72. // Reboot sender: old packets and old ACKs cannot reactivate a retired session.
  73. a2 := testProtocol(t)
  74. establish(t, a2, b)
  75. if _, _, _, _, err = b.open(oldAck); err == nil {
  76. t.Fatal("retired peer session accepted")
  77. }
  78. if _, _, _, _, err = b.open(forward); err == nil {
  79. t.Fatal("old data accepted after sender restart")
  80. }
  81. fresh := testSeal(t, a2, 0, []byte("after restart"), zeroSession)
  82. if _, _, _, _, err = b.open(fresh); err != nil {
  83. t.Fatal(err)
  84. }
  85. // Reboot receiver: even authentic recordings target its obsolete boot ID.
  86. b2 := testProtocol(t)
  87. if _, _, _, _, err = b2.open(fresh); err == nil {
  88. t.Fatal("old data accepted after receiver restart")
  89. }
  90. establish(t, a2, b2)
  91. if _, _, _, _, err = b2.open(testSeal(t, a2, 0, []byte("new receiver"), zeroSession)); err != nil {
  92. t.Fatal(err)
  93. }
  94. }
  95. func TestHelloDoesNotReplaceSession(t *testing.T) {
  96. a, b := testProtocol(t), testProtocol(t)
  97. establish(t, a, b)
  98. stranger := testProtocol(t)
  99. _, _, _, _, err := b.open(testSeal(t, stranger, flagHello, nil, zeroSession))
  100. if err != nil {
  101. t.Fatal(err)
  102. }
  103. if b.remote != a.local {
  104. t.Fatal("HELLO replaced established session")
  105. }
  106. wrong, err := newProtocol("a completely different shared secret")
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. if _, _, _, _, err = b.open(testSeal(t, wrong, flagHello, nil, zeroSession)); err == nil {
  111. t.Fatal("wrong PSK accepted")
  112. }
  113. }
  114. func TestReplayWindow(t *testing.T) {
  115. var w replayWindow
  116. for _, n := range []uint64{1, 3, 2, 66, 65} {
  117. if !w.accept(n) {
  118. t.Fatalf("valid counter %d rejected", n)
  119. }
  120. }
  121. for _, n := range []uint64{0, 1, 2, 3, 65, 66} {
  122. if w.accept(n) {
  123. t.Fatalf("invalid counter %d accepted", n)
  124. }
  125. }
  126. }
  127. func TestHandshakeConfirmationRetry(t *testing.T) {
  128. a, b := testProtocol(t), testProtocol(t)
  129. hello := testSeal(t, a, flagHello, nil, zeroSession)
  130. _, _, sender, _, err := b.open(hello)
  131. if err != nil {
  132. t.Fatal(err)
  133. }
  134. ack := testSeal(t, b, flagAck, nil, sender)
  135. _, _, _, _, err = a.open(ack)
  136. if err != nil {
  137. t.Fatal(err)
  138. }
  139. // First confirmation is lost. Repeated HELLO -> ACK -> CONFIRM still works.
  140. establish(t, a, b)
  141. if _, _, _, _, err = b.open(testSeal(t, a, 0, []byte("data"), zeroSession)); err != nil {
  142. t.Fatal(err)
  143. }
  144. }