wire_auth_test.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package ike
  2. import (
  3. "bytes"
  4. "errors"
  5. "testing"
  6. "vocat/internal/vowifi"
  7. )
  8. func TestPayloadAndProposalWireRoundTrip(t *testing.T) {
  9. offered := proposal{
  10. Number: 1,
  11. Protocol: protocolIKE,
  12. Transforms: []transform{
  13. {Type: transformEncryption, ID: encryptionAESCBC, KeyLength: 128},
  14. {Type: transformPRF, ID: prfHMACSHA1},
  15. {Type: transformIntegrity, ID: integrityHMACSHA1_96},
  16. {Type: transformDH, ID: dhMODP1024},
  17. },
  18. }
  19. sa, err := marshalProposals([]proposal{offered})
  20. if err != nil {
  21. t.Fatalf("marshalProposals() error = %v", err)
  22. }
  23. first, wire, err := marshalPayloadChain([]payload{
  24. {Type: payloadSA, Body: sa},
  25. {Type: payloadNonce, Body: bytes.Repeat([]byte{0xaa}, 32)},
  26. })
  27. if err != nil {
  28. t.Fatalf("marshalPayloadChain() error = %v", err)
  29. }
  30. if first != payloadSA || len(wire) < 8 || wire[0] != payloadNonce {
  31. t.Fatalf("unexpected payload chain header: first=%d wire=%x", first, wire[:8])
  32. }
  33. decoded, err := parsePayloadChain(first, wire)
  34. if err != nil {
  35. t.Fatalf("parsePayloadChain() error = %v", err)
  36. }
  37. if len(decoded) != 2 || decoded[0].Type != payloadSA || decoded[1].Type != payloadNonce {
  38. t.Fatalf("decoded payload chain = %#v", decoded)
  39. }
  40. proposals, err := parseProposals(decoded[0].Body)
  41. if err != nil {
  42. t.Fatalf("parseProposals() error = %v", err)
  43. }
  44. if len(proposals) != 1 || len(proposals[0].Transforms) != 4 ||
  45. proposals[0].Transforms[0].KeyLength != 128 {
  46. t.Fatalf("decoded proposal = %#v", proposals)
  47. }
  48. }
  49. func TestInitialEAPOnlyAuthCarriesAPNIDrAndNotify(t *testing.T) {
  50. idi := payload{Type: payloadIDi, Body: []byte{3, 0, 0, 0, 'u'}}
  51. idr := payload{Type: payloadIDr, Body: []byte{2, 0, 0, 0, 'i', 'm', 's'}}
  52. payloads := buildInitialEAPOnlyAuth(
  53. idi,
  54. idr,
  55. []byte{1, 2, 3},
  56. dualStackTrafficSelectors(payloadTSi),
  57. dualStackTrafficSelectors(payloadTSr),
  58. )
  59. if len(payloads) != 7 || payloads[0].Type != payloadIDi || payloads[1].Type != payloadIDr {
  60. t.Fatalf("initial auth payload order = %#v", payloads)
  61. }
  62. if got := string(payloads[1].Body[4:]); got != "ims" || payloads[1].Body[0] != 2 {
  63. t.Fatalf("IDr = type %d value %q, want ID_FQDN ims", payloads[1].Body[0], got)
  64. }
  65. kind, data, err := parseNotify(payloads[2])
  66. if err != nil {
  67. t.Fatalf("parseNotify() error = %v", err)
  68. }
  69. if kind != notifyEAPOnlyAuth || len(data) != 0 {
  70. t.Fatalf("notify = %d/%x, want EAP_ONLY_AUTHENTICATION", kind, data)
  71. }
  72. for _, kind := range []uint8{payloadTSi, payloadTSr} {
  73. item, err := onePayload(payloads, kind)
  74. if err != nil {
  75. t.Fatalf("onePayload(%d) error = %v", kind, err)
  76. }
  77. selectors, err := parseTrafficSelectors(item)
  78. if err != nil {
  79. t.Fatalf("parseTrafficSelectors(%d) error = %v", kind, err)
  80. }
  81. if len(selectors) != 2 || selectors[0].StartIP.To4() == nil || selectors[1].StartIP.To4() != nil {
  82. t.Fatalf("dual-stack selectors = %#v", selectors)
  83. }
  84. }
  85. }
  86. func TestResponderIDrValidatorsSeparateEPDGAndAPN(t *testing.T) {
  87. epdg := payload{
  88. Type: payloadIDr,
  89. Body: append([]byte{2, 0, 0, 0}, []byte("epdg.epc.mnc015.mcc234.pub.3gppnetwork.org")...),
  90. }
  91. if err := validateFQDNIDr(epdg, "epdg.epc.mnc015.mcc234.pub.3gppnetwork.org", "initial ePDG"); err != nil {
  92. t.Fatalf("valid initial IDr rejected: %v", err)
  93. }
  94. apn := payload{Type: payloadIDr, Body: []byte{2, 0, 0, 0, 'i', 'm', 's'}}
  95. if err := validateFQDNIDr(apn, "ims", "final APN"); err != nil {
  96. t.Fatalf("valid final IDr rejected: %v", err)
  97. }
  98. wrongType := apn
  99. wrongType.Body = append([]byte(nil), apn.Body...)
  100. wrongType.Body[0] = 11
  101. if err := validateFQDNIDr(wrongType, "ims", "final APN"); err == nil {
  102. t.Fatal("non-ID_FQDN final IDr was accepted")
  103. }
  104. if err := validateFQDNIDr(epdg, "ims", "final APN"); err == nil {
  105. t.Fatal("ePDG identity was accepted as the APN identity")
  106. }
  107. }
  108. func TestFinalEAPResponderAUTHValidAndInvalidNeverAllowed(t *testing.T) {
  109. suite := legacyTestSuite()
  110. msk := bytes.Repeat([]byte{0x10}, 64)
  111. initialResponse := bytes.Repeat([]byte{0x20}, 96)
  112. initiatorNonce := bytes.Repeat([]byte{0x30}, 32)
  113. skpr := bytes.Repeat([]byte{0x40}, 20)
  114. idr := payload{Type: payloadIDr, Body: append([]byte{2, 0, 0, 0}, []byte("epdg.example")...)}
  115. signed, err := responderSignedOctets(initialResponse, initiatorNonce, suite, skpr, idr)
  116. if err != nil {
  117. t.Fatalf("responderSignedOctets() error = %v", err)
  118. }
  119. padded, _ := prf(suite, msk, []byte("Key Pad for IKEv2"))
  120. value, _ := prf(suite, padded, signed)
  121. auth := payload{Type: payloadAuth, Body: append([]byte{authMethodSharedKeyMIC, 0, 0, 0}, value...)}
  122. if err := verifyEAPResponderAUTH(auth, msk, initialResponse, initiatorNonce, suite, skpr, idr); err != nil {
  123. t.Fatalf("valid final responder AUTH rejected: %v", err)
  124. }
  125. auth.Body[len(auth.Body)-1] ^= 1
  126. if err := verifyEAPResponderAUTH(auth, msk, initialResponse, initiatorNonce, suite, skpr, idr); err == nil {
  127. t.Fatal("invalid final responder AUTH was accepted")
  128. }
  129. status, _, err := validateInitialResponderAUTH(
  130. []payload{idr},
  131. initialResponse,
  132. initiatorNonce,
  133. suite,
  134. skpr,
  135. "epdg.example",
  136. "epdg.example",
  137. nil,
  138. nil,
  139. false,
  140. )
  141. if status != vowifi.ResponderAUTHMissing || !errors.Is(err, vowifi.ErrResponderAUTHRequired) {
  142. t.Fatalf("strict missing initial AUTH = status %q err %v", status, err)
  143. }
  144. status, _, err = validateInitialResponderAUTH(
  145. []payload{idr},
  146. initialResponse,
  147. initiatorNonce,
  148. suite,
  149. skpr,
  150. "epdg.example",
  151. "epdg.example",
  152. nil,
  153. nil,
  154. true,
  155. )
  156. if status != vowifi.ResponderAUTHMissing || err != nil {
  157. t.Fatalf("EAP-only deferred initial AUTH = status %q err %v", status, err)
  158. }
  159. }
  160. func TestConfigurationIPv6PrefixIsMandatoryAndPreserved(t *testing.T) {
  161. ipv6 := bytes.Repeat([]byte{0x20}, 16)
  162. validBody := []byte{configReply, 0, 0, 0, 0, configInternalIPv6Address, 0, 17}
  163. validBody = append(validBody, ipv6...)
  164. validBody = append(validBody, 64)
  165. configuration, err := parseConfiguration(payload{Type: payloadCP, Body: validBody})
  166. if err != nil {
  167. t.Fatalf("parseConfiguration(valid IPv6) error = %v", err)
  168. }
  169. if configuration.IPv6Prefix != 64 || !bytes.Equal(configuration.LocalIPv6, ipv6) {
  170. t.Fatalf("IPv6 configuration = %#v", configuration)
  171. }
  172. invalidBody := []byte{configReply, 0, 0, 0, 0, configInternalIPv6Address, 0, 16}
  173. invalidBody = append(invalidBody, ipv6...)
  174. if _, err := parseConfiguration(payload{Type: payloadCP, Body: invalidBody}); err == nil {
  175. t.Fatal("16-byte INTERNAL_IP6_ADDRESS without prefix was accepted")
  176. }
  177. }