provider.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. package ike
  2. import (
  3. "context"
  4. "crypto"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "crypto/x509"
  8. "encoding/binary"
  9. "encoding/hex"
  10. "errors"
  11. "fmt"
  12. "io"
  13. "net"
  14. "strings"
  15. "sync"
  16. "time"
  17. "vocat/internal/vowifi"
  18. )
  19. type Config struct {
  20. Random io.Reader
  21. Resolver *net.Resolver
  22. Dialer *net.Dialer
  23. RootCAs *x509.CertPool
  24. ResponderPublicKey crypto.PublicKey
  25. ServerName string
  26. Timeout time.Duration
  27. KeepaliveInterval time.Duration
  28. Installer ChildSAInstaller
  29. IdentityType uint8
  30. APN string
  31. }
  32. type Provider struct {
  33. config Config
  34. transportFactory func(context.Context, transportConfig, vowifi.ProxyRoute, string) (datagramTransport, error)
  35. }
  36. func NewProvider(config Config) (*Provider, error) {
  37. if config.Random == nil {
  38. config.Random = rand.Reader
  39. }
  40. if config.Resolver == nil {
  41. config.Resolver = net.DefaultResolver
  42. }
  43. if config.Dialer == nil {
  44. config.Dialer = &net.Dialer{}
  45. }
  46. if config.Timeout < 0 {
  47. return nil, errors.New("ike: timeout must not be negative")
  48. }
  49. if config.Timeout == 0 {
  50. config.Timeout = 12 * time.Second
  51. }
  52. if config.KeepaliveInterval < 0 {
  53. return nil, errors.New("ike: keepalive interval must not be negative")
  54. }
  55. if config.KeepaliveInterval == 0 {
  56. config.KeepaliveInterval = 20 * time.Second
  57. }
  58. if config.IdentityType == 0 {
  59. config.IdentityType = 3 // ID_RFC822_ADDR, carrying the permanent NAI.
  60. }
  61. config.APN = strings.TrimSpace(config.APN)
  62. if config.APN == "" {
  63. config.APN = "ims"
  64. }
  65. if len(config.APN) > 253 || strings.ContainsAny(config.APN, " \t\r\n/:@") {
  66. return nil, errors.New("ike: APN is invalid")
  67. }
  68. if config.Installer == nil {
  69. config.Installer = defaultChildSAInstaller()
  70. }
  71. return &Provider{config: config, transportFactory: newDatagramTransport}, nil
  72. }
  73. func (provider *Provider) Start(ctx context.Context, request vowifi.TunnelRequest) (vowifi.TunnelSession, error) {
  74. if provider == nil {
  75. return nil, errors.New("ike: nil provider")
  76. }
  77. if ctx == nil {
  78. ctx = context.Background()
  79. }
  80. if request.AKA == nil {
  81. return nil, errors.New("ike: AKA provider is required")
  82. }
  83. epdg := strings.TrimSpace(request.EPDG)
  84. if epdg == "" || strings.ContainsAny(epdg, " \t\r\n/:") {
  85. return nil, errors.New("ike: ePDG must be a hostname")
  86. }
  87. aka, err := newAKAClient(request.Identity, request.AKA)
  88. if err != nil {
  89. return nil, err
  90. }
  91. transport, err := provider.transportFactory(ctx, transportConfig{
  92. Resolver: provider.config.Resolver,
  93. Dialer: provider.config.Dialer,
  94. Timeout: provider.config.Timeout,
  95. }, request.Proxy, epdg)
  96. if err != nil {
  97. return nil, err
  98. }
  99. closeTransport := true
  100. defer func() {
  101. if closeTransport {
  102. _ = transport.Close()
  103. }
  104. }()
  105. group := uint16(dhMODP2048)
  106. legacyFirst := request.Identity.HomeMCC == "234" && request.Identity.HomeMNC == "15"
  107. if legacyFirst {
  108. group = dhMODP1024
  109. }
  110. dh, err := newDHExchange(group, provider.config.Random)
  111. if err != nil {
  112. return nil, err
  113. }
  114. var initiatorSPI [8]byte
  115. if err := fillNonzero(provider.config.Random, initiatorSPI[:]); err != nil {
  116. return nil, err
  117. }
  118. initiatorNonce := make([]byte, 32)
  119. if _, err := io.ReadFull(provider.config.Random, initiatorNonce); err != nil {
  120. return nil, fmt.Errorf("ike: generate initiator nonce: %w", err)
  121. }
  122. ikeProposalBody, err := marshalProposals([]proposal{ikeOffer(group, legacyFirst)})
  123. if err != nil {
  124. return nil, err
  125. }
  126. keBody := make([]byte, 4+len(dh.Public))
  127. binary.BigEndian.PutUint16(keBody[0:2], group)
  128. copy(keBody[4:], dh.Public)
  129. localAddress := transport.LocalAddr()
  130. remoteAddress := transport.RemoteAddr()
  131. if localAddress == nil || remoteAddress == nil {
  132. return nil, errors.New("ike: transport did not expose UDP endpoints")
  133. }
  134. sourceHash, err := natDetectionHash(initiatorSPI, [8]byte{}, localAddress.IP, uint16(localAddress.Port))
  135. if err != nil {
  136. return nil, err
  137. }
  138. destinationHash, err := natDetectionHash(initiatorSPI, [8]byte{}, remoteAddress.IP, uint16(remoteAddress.Port))
  139. if err != nil {
  140. return nil, err
  141. }
  142. initPayloads := []payload{
  143. {Type: payloadSA, Body: ikeProposalBody},
  144. {Type: payloadKE, Body: keBody},
  145. {Type: payloadNonce, Body: initiatorNonce},
  146. makeNotify(notifyNATSource, sourceHash),
  147. makeNotify(notifyNATDestination, destinationHash),
  148. }
  149. first, initBody, err := marshalPayloadChain(initPayloads)
  150. if err != nil {
  151. return nil, err
  152. }
  153. initRequest := ikeHeader{
  154. InitiatorSPI: initiatorSPI,
  155. NextPayload: first,
  156. Exchange: exchangeIKEInit,
  157. Flags: flagInitiator,
  158. MessageID: 0,
  159. }.marshal(initBody)
  160. initResponse, err := transport.RoundTrip(ctx, initRequest)
  161. if err != nil {
  162. return nil, err
  163. }
  164. responseHeader, responseBody, err := validateResponse(initResponse, initiatorSPI, [8]byte{}, exchangeIKEInit, 0)
  165. if err != nil {
  166. return nil, err
  167. }
  168. if responseHeader.ResponderSPI == [8]byte{} {
  169. return nil, errors.New("ike: responder returned a zero SPI")
  170. }
  171. initResponsePayloads, err := parsePayloadChain(responseHeader.NextPayload, responseBody)
  172. if err != nil {
  173. return nil, err
  174. }
  175. if err := rejectFatalNotifications(initResponsePayloads); err != nil {
  176. return nil, err
  177. }
  178. saPayload, err := onePayload(initResponsePayloads, payloadSA)
  179. if err != nil {
  180. return nil, err
  181. }
  182. selectedProposals, err := parseProposals(saPayload.Body)
  183. if err != nil || len(selectedProposals) != 1 {
  184. return nil, errors.New("ike: responder did not select exactly one IKE proposal")
  185. }
  186. ikeSuite, err := parseIKESuite(selectedProposals[0])
  187. if err != nil {
  188. return nil, err
  189. }
  190. if ikeSuite.DHID != group {
  191. return nil, fmt.Errorf("ike: responder selected DH group %d but KE used group %d", ikeSuite.DHID, group)
  192. }
  193. responderKE, err := onePayload(initResponsePayloads, payloadKE)
  194. if err != nil {
  195. return nil, err
  196. }
  197. if len(responderKE.Body) < 4 || binary.BigEndian.Uint16(responderKE.Body[0:2]) != group {
  198. return nil, errors.New("ike: responder KE group does not match the selected proposal")
  199. }
  200. sharedSecret, err := dh.shared(responderKE.Body[4:])
  201. if err != nil {
  202. return nil, err
  203. }
  204. responderNoncePayload, err := onePayload(initResponsePayloads, payloadNonce)
  205. if err != nil {
  206. return nil, err
  207. }
  208. if len(responderNoncePayload.Body) < 16 || len(responderNoncePayload.Body) > 256 {
  209. return nil, errors.New("ike: responder nonce length is outside 16..256 bytes")
  210. }
  211. responderNonce := responderNoncePayload.Body
  212. keys, err := deriveIKEKeys(
  213. ikeSuite,
  214. sharedSecret,
  215. initiatorNonce,
  216. responderNonce,
  217. initiatorSPI,
  218. responseHeader.ResponderSPI,
  219. )
  220. if err != nil {
  221. return nil, err
  222. }
  223. natDetected, err := detectNAT(
  224. initResponsePayloads,
  225. initiatorSPI,
  226. responseHeader.ResponderSPI,
  227. transport.LocalAddr(),
  228. transport.RemoteAddr(),
  229. )
  230. if err != nil {
  231. return nil, err
  232. }
  233. if request.Proxy.Mode == vowifi.ProxyModeSOCKS5 {
  234. natDetected = true
  235. }
  236. if natDetected {
  237. if err := transport.Float(ctx); err != nil {
  238. return nil, err
  239. }
  240. }
  241. var childInboundSPIBytes [4]byte
  242. if err := fillNonzero(provider.config.Random, childInboundSPIBytes[:]); err != nil {
  243. return nil, err
  244. }
  245. childInboundSPI := binary.BigEndian.Uint32(childInboundSPIBytes[:])
  246. childOfferBody, err := marshalProposals([]proposal{espOffer(childInboundSPIBytes[:], legacyFirst)})
  247. if err != nil {
  248. return nil, err
  249. }
  250. idi := payload{Type: payloadIDi, Body: append([]byte{provider.config.IdentityType, 0, 0, 0}, aka.identity...)}
  251. requestedIDr := payload{Type: payloadIDr, Body: append([]byte{2, 0, 0, 0}, []byte(provider.config.APN)...)}
  252. tsi := dualStackTrafficSelectors(payloadTSi)
  253. tsr := dualStackTrafficSelectors(payloadTSr)
  254. firstAuthPayloads := buildInitialEAPOnlyAuth(idi, requestedIDr, childOfferBody, tsi, tsr)
  255. authHeader := ikeHeader{
  256. InitiatorSPI: initiatorSPI,
  257. ResponderSPI: responseHeader.ResponderSPI,
  258. Exchange: exchangeIKEAuth,
  259. Flags: flagInitiator,
  260. MessageID: 1,
  261. }
  262. authRequest, err := encryptPayloads(authHeader, firstAuthPayloads, ikeSuite, keys.SKei, keys.SKai, provider.config.Random)
  263. if err != nil {
  264. return nil, err
  265. }
  266. authResponse, err := transport.RoundTrip(ctx, authRequest)
  267. if err != nil {
  268. return nil, err
  269. }
  270. authResponseHeader, authResponsePayloads, err := decryptAndValidate(
  271. authResponse, initiatorSPI, responseHeader.ResponderSPI, exchangeIKEAuth, 1, ikeSuite, keys,
  272. )
  273. if err != nil {
  274. return nil, err
  275. }
  276. _ = authResponseHeader
  277. serverName := strings.TrimSpace(provider.config.ServerName)
  278. if serverName == "" {
  279. serverName = epdg
  280. }
  281. responderAUTH, responderID, err := validateInitialResponderAUTH(
  282. authResponsePayloads,
  283. initResponse,
  284. initiatorNonce,
  285. ikeSuite,
  286. keys.SKpr,
  287. serverName,
  288. serverName,
  289. provider.config.RootCAs,
  290. provider.config.ResponderPublicKey,
  291. true, // RFC 5998 EAP-only authentication defers responder AUTH.
  292. )
  293. if err != nil {
  294. return nil, err
  295. }
  296. messageID := uint32(1)
  297. currentPayloads := authResponsePayloads
  298. for round := 0; round < 10; round++ {
  299. eapPayload, err := onePayload(currentPayloads, payloadEAP)
  300. if err != nil {
  301. return nil, fmt.Errorf("ike: IKE_AUTH EAP round %d: %w", round+1, err)
  302. }
  303. action, err := aka.handle(ctx, eapPayload.Body)
  304. if err != nil {
  305. return nil, err
  306. }
  307. if action.Success {
  308. break
  309. }
  310. if len(action.Response) == 0 {
  311. return nil, errors.New("ike: EAP state machine produced no response")
  312. }
  313. messageID++
  314. eapRequest, err := encryptPayloads(ikeHeader{
  315. InitiatorSPI: initiatorSPI,
  316. ResponderSPI: responseHeader.ResponderSPI,
  317. Exchange: exchangeIKEAuth,
  318. Flags: flagInitiator,
  319. MessageID: messageID,
  320. }, []payload{{Type: payloadEAP, Body: action.Response}}, ikeSuite, keys.SKei, keys.SKai, provider.config.Random)
  321. if err != nil {
  322. return nil, err
  323. }
  324. eapResponse, err := transport.RoundTrip(ctx, eapRequest)
  325. if err != nil {
  326. return nil, err
  327. }
  328. _, currentPayloads, err = decryptAndValidate(
  329. eapResponse, initiatorSPI, responseHeader.ResponderSPI, exchangeIKEAuth, messageID, ikeSuite, keys,
  330. )
  331. if err != nil {
  332. return nil, err
  333. }
  334. if round == 9 {
  335. return nil, errors.New("ike: EAP exchange exceeded ten IKE_AUTH rounds")
  336. }
  337. }
  338. if !aka.challengeComplete || len(aka.keys.MSK) != 64 {
  339. return nil, errors.New("ike: EAP-AKA did not produce an authenticated MSK")
  340. }
  341. initiatorAUTH, err := makeEAPInitiatorAUTH(
  342. aka.keys.MSK,
  343. initRequest,
  344. responderNonce,
  345. ikeSuite,
  346. keys.SKpi,
  347. idi,
  348. )
  349. if err != nil {
  350. return nil, err
  351. }
  352. messageID++
  353. finalRequest, err := encryptPayloads(ikeHeader{
  354. InitiatorSPI: initiatorSPI,
  355. ResponderSPI: responseHeader.ResponderSPI,
  356. Exchange: exchangeIKEAuth,
  357. Flags: flagInitiator,
  358. MessageID: messageID,
  359. }, []payload{initiatorAUTH}, ikeSuite, keys.SKei, keys.SKai, provider.config.Random)
  360. if err != nil {
  361. return nil, err
  362. }
  363. finalResponse, err := transport.RoundTrip(ctx, finalRequest)
  364. if err != nil {
  365. return nil, err
  366. }
  367. _, finalPayloads, err := decryptAndValidate(
  368. finalResponse, initiatorSPI, responseHeader.ResponderSPI, exchangeIKEAuth, messageID, ikeSuite, keys,
  369. )
  370. if err != nil {
  371. return nil, err
  372. }
  373. if err := rejectFatalNotifications(finalPayloads); err != nil {
  374. return nil, err
  375. }
  376. finalAUTHs := payloadsOfType(finalPayloads, payloadAuth)
  377. if len(finalAUTHs) != 1 {
  378. return nil, fmt.Errorf("%w: final EAP-only response must contain exactly one MSK AUTH payload", vowifi.ErrResponderAUTHRequired)
  379. }
  380. if len(responderID.Body) == 0 {
  381. return nil, errors.New("ike: EAP-only exchange has no initial ePDG IDr for the responder AUTH transcript")
  382. }
  383. finalIDs := payloadsOfType(finalPayloads, payloadIDr)
  384. if len(finalIDs) > 1 {
  385. return nil, errors.New("ike: duplicate final responder IDr payload")
  386. }
  387. if len(finalIDs) == 1 {
  388. if err := validateFQDNIDr(finalIDs[0], provider.config.APN, "final APN"); err != nil {
  389. return nil, fmt.Errorf("ike: final APN IDr: %w", err)
  390. }
  391. }
  392. if err := verifyEAPResponderAUTH(
  393. finalAUTHs[0],
  394. aka.keys.MSK,
  395. initResponse,
  396. initiatorNonce,
  397. ikeSuite,
  398. keys.SKpr,
  399. responderID,
  400. ); err != nil {
  401. return nil, err
  402. }
  403. responderAUTH = vowifi.ResponderAUTHVerified
  404. childSA, err := onePayload(finalPayloads, payloadSA)
  405. if err != nil {
  406. return nil, err
  407. }
  408. childProposals, err := parseProposals(childSA.Body)
  409. if err != nil || len(childProposals) != 1 {
  410. return nil, errors.New("ike: responder did not select exactly one ESP proposal")
  411. }
  412. childSuite, err := parseESPSuite(childProposals[0])
  413. if err != nil {
  414. return nil, err
  415. }
  416. childOutboundSPI := binary.BigEndian.Uint32(childProposals[0].SPI)
  417. finalTSi, err := onePayload(finalPayloads, payloadTSi)
  418. if err != nil {
  419. return nil, err
  420. }
  421. finalTSr, err := onePayload(finalPayloads, payloadTSr)
  422. if err != nil {
  423. return nil, err
  424. }
  425. initiatorSelectors, err := parseTrafficSelectors(finalTSi)
  426. if err != nil {
  427. return nil, err
  428. }
  429. responderSelectors, err := parseTrafficSelectors(finalTSr)
  430. if err != nil {
  431. return nil, err
  432. }
  433. cpPayload, err := onePayload(finalPayloads, payloadCP)
  434. if err != nil {
  435. return nil, err
  436. }
  437. network, err := parseConfiguration(cpPayload)
  438. if err != nil {
  439. return nil, err
  440. }
  441. if network.LocalIPv4 == nil && network.LocalIPv6 == nil {
  442. return nil, errors.New("ike: responder did not assign an inner IP address")
  443. }
  444. network.PCSCF = pcscfForAssignedFamilies(
  445. network.PCSCF,
  446. network.LocalIPv4 != nil,
  447. network.LocalIPv6 != nil,
  448. )
  449. if len(network.PCSCF) == 0 {
  450. return nil, errors.New("ike: responder did not provide a P-CSCF matching an assigned address family")
  451. }
  452. outboundEncryption, outboundIntegrity, inboundEncryption, inboundIntegrity, err := deriveChildSAKeys(
  453. ikeSuite, childSuite, keys.SKd, initiatorNonce, responderNonce,
  454. )
  455. if err != nil {
  456. return nil, err
  457. }
  458. encryptionName, integrityName := espSuiteNames(childSuite)
  459. name := tunnelName(request.DeviceID)
  460. relay := newSessionRelay(
  461. transport,
  462. ikeSuite,
  463. keys,
  464. initiatorSPI,
  465. responseHeader.ResponderSPI,
  466. natDetected,
  467. provider.config.KeepaliveInterval,
  468. )
  469. installed, err := provider.config.Installer.Install(ctx, ChildSAConfig{
  470. Name: name,
  471. OuterLocal: append(net.IP(nil), transport.LocalAddr().IP...),
  472. OuterRemote: append(net.IP(nil), transport.RemoteAddr().IP...),
  473. InnerLocalIPv4: append(net.IP(nil), network.LocalIPv4...),
  474. InnerLocalIPv6: append(net.IP(nil), network.LocalIPv6...),
  475. InnerIPv6Prefix: network.IPv6Prefix,
  476. PCSCF: cloneIPs(network.PCSCF),
  477. DNS: cloneIPs(network.DNS),
  478. InboundSPI: childInboundSPI,
  479. OutboundSPI: childOutboundSPI,
  480. Encryption: encryptionName,
  481. Integrity: integrityName,
  482. InboundEncKey: inboundEncryption,
  483. InboundAuthKey: inboundIntegrity,
  484. OutboundEncKey: outboundEncryption,
  485. OutboundAuthKey: outboundIntegrity,
  486. InitiatorSelectors: initiatorSelectors,
  487. ResponderSelectors: responderSelectors,
  488. UDPEncapsulation: natDetected,
  489. ProxyMode: request.Proxy.Mode,
  490. Relay: relay,
  491. })
  492. if err != nil {
  493. _ = relay.Close()
  494. return nil, fmt.Errorf("ike: install CHILD_SA: %w", err)
  495. }
  496. if installed == nil {
  497. _ = relay.Close()
  498. return nil, errors.New("ike: CHILD_SA installer returned a nil handle")
  499. }
  500. dataplaneMode := "unknown"
  501. if mode, ok := installed.(DataplaneEvidence); ok {
  502. switch mode.DataplaneMode() {
  503. case "userspace", "xfrm":
  504. dataplaneMode = mode.DataplaneMode()
  505. }
  506. }
  507. evidence := vowifi.TunnelEvidence{
  508. Established: true,
  509. Name: name,
  510. DataplaneMode: dataplaneMode,
  511. LocalIPv4: ipString(network.LocalIPv4),
  512. LocalIPv6: ipString(network.LocalIPv6),
  513. PCSCF: ipStrings(network.PCSCF),
  514. ResponderAUTH: responderAUTH,
  515. IKEEncryption: fmt.Sprintf("aes-cbc-%d", ikeSuite.EncryptionBits),
  516. IKEIntegrity: ikeIntegrityName(ikeSuite.IntegrityID),
  517. IKEDHGroup: dhName(ikeSuite.DHID),
  518. ESPEncryption: encryptionName,
  519. ESPIntegrity: integrityName,
  520. }
  521. session := &Session{
  522. evidence: evidence,
  523. network: NetworkEvidence{
  524. LocalIPv4: ipString(network.LocalIPv4),
  525. LocalIPv6: ipString(network.LocalIPv6),
  526. DNS: ipStrings(network.DNS),
  527. PCSCF: ipStrings(network.PCSCF),
  528. DataplaneMode: dataplaneMode,
  529. },
  530. child: installed,
  531. relay: relay,
  532. transport: transport,
  533. }
  534. closeTransport = false
  535. return session, nil
  536. }
  537. func buildInitialEAPOnlyAuth(
  538. idi payload,
  539. requestedIDr payload,
  540. childOfferBody []byte,
  541. tsi payload,
  542. tsr payload,
  543. ) []payload {
  544. return []payload{
  545. idi,
  546. requestedIDr,
  547. makeNotify(notifyEAPOnlyAuth, nil),
  548. {Type: payloadSA, Body: append([]byte(nil), childOfferBody...)},
  549. tsi,
  550. tsr,
  551. configurationRequest(),
  552. }
  553. }
  554. func ikeOffer(group uint16, legacyFirst bool) proposal {
  555. transforms := []transform{
  556. {Type: transformEncryption, ID: encryptionAESCBC, KeyLength: 128},
  557. {Type: transformEncryption, ID: encryptionAESCBC, KeyLength: 256},
  558. {Type: transformPRF, ID: prfHMACSHA1},
  559. {Type: transformPRF, ID: prfHMACSHA256},
  560. {Type: transformIntegrity, ID: integrityHMACSHA1_96},
  561. {Type: transformIntegrity, ID: integrityHMACSHA256_128},
  562. {Type: transformDH, ID: group},
  563. }
  564. if !legacyFirst {
  565. transforms[2], transforms[3] = transforms[3], transforms[2]
  566. transforms[4], transforms[5] = transforms[5], transforms[4]
  567. }
  568. return proposal{Number: 1, Protocol: protocolIKE, Transforms: transforms}
  569. }
  570. func espOffer(spi []byte, legacyFirst bool) proposal {
  571. transforms := []transform{
  572. {Type: transformEncryption, ID: encryptionAESCBC, KeyLength: 128},
  573. {Type: transformEncryption, ID: encryptionAESCBC, KeyLength: 256},
  574. {Type: transformIntegrity, ID: integrityHMACSHA1_96},
  575. {Type: transformIntegrity, ID: integrityHMACSHA256_128},
  576. {Type: transformESN, ID: 0},
  577. }
  578. if !legacyFirst {
  579. transforms[2], transforms[3] = transforms[3], transforms[2]
  580. }
  581. return proposal{Number: 1, Protocol: protocolESP, SPI: append([]byte(nil), spi...), Transforms: transforms}
  582. }
  583. func validateResponse(
  584. packet []byte,
  585. initiatorSPI [8]byte,
  586. responderSPI [8]byte,
  587. exchange uint8,
  588. messageID uint32,
  589. ) (ikeHeader, []byte, error) {
  590. header, body, err := parseIKEPacket(packet)
  591. if err != nil {
  592. return ikeHeader{}, nil, err
  593. }
  594. if header.InitiatorSPI != initiatorSPI ||
  595. (responderSPI != [8]byte{} && header.ResponderSPI != responderSPI) ||
  596. header.Exchange != exchange ||
  597. header.MessageID != messageID ||
  598. header.Flags&flagResponse == 0 ||
  599. header.Flags&flagInitiator != 0 {
  600. return ikeHeader{}, nil, fmt.Errorf("%w: response header does not match the request", errUnexpectedPacket)
  601. }
  602. return header, body, nil
  603. }
  604. func decryptAndValidate(
  605. packet []byte,
  606. initiatorSPI [8]byte,
  607. responderSPI [8]byte,
  608. exchange uint8,
  609. messageID uint32,
  610. suite negotiatedSuite,
  611. keys ikeKeys,
  612. ) (ikeHeader, []payload, error) {
  613. header, payloads, err := decryptPayloads(packet, suite, keys.SKer, keys.SKar)
  614. if err != nil {
  615. return ikeHeader{}, nil, err
  616. }
  617. if header.InitiatorSPI != initiatorSPI ||
  618. header.ResponderSPI != responderSPI ||
  619. header.Exchange != exchange ||
  620. header.MessageID != messageID ||
  621. header.Flags&flagResponse == 0 ||
  622. header.Flags&flagInitiator != 0 {
  623. return ikeHeader{}, nil, fmt.Errorf("%w: encrypted response header does not match the request", errUnexpectedPacket)
  624. }
  625. return header, payloads, nil
  626. }
  627. func rejectFatalNotifications(payloads []payload) error {
  628. for _, item := range payloadsOfType(payloads, payloadNotify) {
  629. kind, data, err := parseNotify(item)
  630. if err != nil {
  631. return err
  632. }
  633. switch kind {
  634. case notifyNoProposal:
  635. return errors.New("ike: responder reported NO_PROPOSAL_CHOSEN")
  636. case notifyInvalidKE:
  637. if len(data) == 2 {
  638. return fmt.Errorf("ike: responder requires DH group %d", binary.BigEndian.Uint16(data))
  639. }
  640. return errors.New("ike: responder reported INVALID_KE_PAYLOAD")
  641. }
  642. if kind < 16384 {
  643. return fmt.Errorf("ike: responder reported fatal notification %d", kind)
  644. }
  645. }
  646. return nil
  647. }
  648. func detectNAT(
  649. payloads []payload,
  650. initiatorSPI [8]byte,
  651. responderSPI [8]byte,
  652. local *net.UDPAddr,
  653. remote *net.UDPAddr,
  654. ) (bool, error) {
  655. var sourceValue, destinationValue []byte
  656. for _, item := range payloadsOfType(payloads, payloadNotify) {
  657. kind, data, err := parseNotify(item)
  658. if err != nil {
  659. return false, err
  660. }
  661. switch kind {
  662. case notifyNATSource:
  663. sourceValue = data
  664. case notifyNATDestination:
  665. destinationValue = data
  666. }
  667. }
  668. if len(sourceValue) == 0 && len(destinationValue) == 0 {
  669. return false, nil
  670. }
  671. if len(sourceValue) != sha1Size || len(destinationValue) != sha1Size {
  672. return false, errors.New("ike: NAT detection notification has an invalid hash length")
  673. }
  674. expectedSource, err := natDetectionHash(initiatorSPI, responderSPI, remote.IP, uint16(remote.Port))
  675. if err != nil {
  676. return false, err
  677. }
  678. expectedDestination, err := natDetectionHash(initiatorSPI, responderSPI, local.IP, uint16(local.Port))
  679. if err != nil {
  680. return false, err
  681. }
  682. return !equalBytes(sourceValue, expectedSource) || !equalBytes(destinationValue, expectedDestination), nil
  683. }
  684. const sha1Size = 20
  685. func equalBytes(first, second []byte) bool {
  686. if len(first) != len(second) {
  687. return false
  688. }
  689. var difference byte
  690. for index := range first {
  691. difference |= first[index] ^ second[index]
  692. }
  693. return difference == 0
  694. }
  695. func fillNonzero(random io.Reader, destination []byte) error {
  696. for attempt := 0; attempt < 8; attempt++ {
  697. if _, err := io.ReadFull(random, destination); err != nil {
  698. return fmt.Errorf("ike: generate SPI: %w", err)
  699. }
  700. var aggregate byte
  701. for _, value := range destination {
  702. aggregate |= value
  703. }
  704. if aggregate != 0 {
  705. return nil
  706. }
  707. }
  708. return errors.New("ike: random source generated a zero SPI repeatedly")
  709. }
  710. func tunnelName(deviceID string) string {
  711. // IFNAMSIZ leaves 15 visible bytes. Hash the complete stable device ID so
  712. // devices with the same long USB/product prefix never collide at TUNSETIFF.
  713. normalized := strings.ToLower(strings.TrimSpace(deviceID))
  714. digest := sha256.Sum256([]byte(normalized))
  715. return "vocat" + hex.EncodeToString(digest[:5])
  716. }
  717. func ipString(ip net.IP) string {
  718. if ip == nil {
  719. return ""
  720. }
  721. return ip.String()
  722. }
  723. func ipStrings(ips []net.IP) []string {
  724. result := make([]string, 0, len(ips))
  725. for _, ip := range ips {
  726. if value := ipString(ip); value != "" {
  727. result = append(result, value)
  728. }
  729. }
  730. return result
  731. }
  732. func pcscfForAssignedFamilies(ips []net.IP, hasIPv4 bool, hasIPv6 bool) []net.IP {
  733. result := make([]net.IP, 0, len(ips))
  734. seen := make(map[string]struct{}, len(ips))
  735. for _, ip := range ips {
  736. key := ip.String()
  737. if _, duplicate := seen[key]; duplicate {
  738. continue
  739. }
  740. switch {
  741. case ip.To4() != nil && hasIPv4:
  742. result = append(result, append(net.IP(nil), ip...))
  743. seen[key] = struct{}{}
  744. case ip.To4() == nil && ip.To16() != nil && hasIPv6:
  745. result = append(result, append(net.IP(nil), ip...))
  746. seen[key] = struct{}{}
  747. }
  748. }
  749. return result
  750. }
  751. func cloneIPs(ips []net.IP) []net.IP {
  752. result := make([]net.IP, 0, len(ips))
  753. for _, ip := range ips {
  754. result = append(result, append(net.IP(nil), ip...))
  755. }
  756. return result
  757. }
  758. func ikeIntegrityName(identifier uint16) string {
  759. switch identifier {
  760. case integrityHMACSHA1_96:
  761. return "hmac-sha1-96"
  762. case integrityHMACSHA256_128:
  763. return "hmac-sha2-256-128"
  764. default:
  765. return ""
  766. }
  767. }
  768. func dhName(identifier uint16) string {
  769. switch identifier {
  770. case dhMODP1024:
  771. return "modp1024"
  772. case dhMODP2048:
  773. return "modp2048"
  774. default:
  775. return ""
  776. }
  777. }
  778. type NetworkEvidence struct {
  779. LocalIPv4 string
  780. LocalIPv6 string
  781. DNS []string
  782. PCSCF []string
  783. DataplaneMode string
  784. }
  785. type Session struct {
  786. mu sync.Mutex
  787. evidence vowifi.TunnelEvidence
  788. network NetworkEvidence
  789. child ChildSAHandle
  790. relay *sessionRelay
  791. transport datagramTransport
  792. closed bool
  793. }
  794. func (session *Session) Evidence() vowifi.TunnelEvidence {
  795. session.mu.Lock()
  796. defer session.mu.Unlock()
  797. evidence := session.evidence
  798. evidence.PCSCF = append([]string(nil), session.evidence.PCSCF...)
  799. return evidence
  800. }
  801. func (session *Session) Network() NetworkEvidence {
  802. session.mu.Lock()
  803. defer session.mu.Unlock()
  804. network := session.network
  805. network.DNS = append([]string(nil), session.network.DNS...)
  806. network.PCSCF = append([]string(nil), session.network.PCSCF...)
  807. return network
  808. }
  809. func (session *Session) Failures() <-chan error {
  810. session.mu.Lock()
  811. defer session.mu.Unlock()
  812. if notifier, ok := session.child.(DataplaneFailureNotifier); ok {
  813. return notifier.Failures()
  814. }
  815. return nil
  816. }
  817. func (session *Session) Close(ctx context.Context) error {
  818. session.mu.Lock()
  819. if session.closed {
  820. session.mu.Unlock()
  821. return nil
  822. }
  823. session.closed = true
  824. child := session.child
  825. relay := session.relay
  826. transport := session.transport
  827. session.evidence.Established = false
  828. session.child = nil
  829. session.relay = nil
  830. session.transport = nil
  831. session.mu.Unlock()
  832. var errs []error
  833. if child != nil {
  834. if err := child.Close(ctx); err != nil {
  835. errs = append(errs, fmt.Errorf("remove CHILD_SA: %w", err))
  836. }
  837. }
  838. if relay != nil {
  839. if err := relay.Close(); err != nil {
  840. errs = append(errs, fmt.Errorf("close session relay: %w", err))
  841. }
  842. }
  843. if transport != nil {
  844. if err := transport.Close(); err != nil {
  845. errs = append(errs, fmt.Errorf("close IKE transport: %w", err))
  846. }
  847. }
  848. return errors.Join(errs...)
  849. }
  850. var _ vowifi.TunnelProvider = (*Provider)(nil)
  851. var _ vowifi.TunnelSession = (*Session)(nil)
  852. var _ vowifi.RuntimeFailureNotifier = (*Session)(nil)