conjure.go 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127
  1. package tapdance
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/hmac"
  6. "crypto/sha256"
  7. "encoding/binary"
  8. "encoding/hex"
  9. "fmt"
  10. "io"
  11. "math/big"
  12. "net"
  13. "net/http"
  14. "strconv"
  15. "sync"
  16. "time"
  17. pt "git.torproject.org/pluggable-transports/goptlib.git"
  18. "github.com/golang/protobuf/proto"
  19. pb "github.com/refraction-networking/gotapdance/protobuf"
  20. ps "github.com/refraction-networking/gotapdance/tapdance/phantoms"
  21. tls "github.com/refraction-networking/utls"
  22. "gitlab.com/yawning/obfs4.git/common/ntor"
  23. "gitlab.com/yawning/obfs4.git/transports/obfs4"
  24. "golang.org/x/crypto/curve25519"
  25. "golang.org/x/crypto/hkdf"
  26. )
  27. // V6 - Struct to track V6 support and cache result across sessions
  28. type V6 struct {
  29. support bool
  30. include uint
  31. }
  32. // Registrar defines the interface for a service executing
  33. // decoy registrations.
  34. type Registrar interface {
  35. Register(*ConjureSession, context.Context) (*ConjureReg, error)
  36. }
  37. type DecoyRegistrar struct {
  38. // TcpDialer is a custom TCP dailer to use when establishing TCP connections
  39. // to decoys. When nil, Dialer.TcpDialer will be used.
  40. TcpDialer func(context.Context, string, string) (net.Conn, error)
  41. }
  42. func (r DecoyRegistrar) Register(cjSession *ConjureSession, ctx context.Context) (*ConjureReg, error) {
  43. Logger().Debugf("%v Registering V4 and V6 via DecoyRegistrar", cjSession.IDString())
  44. // Choose N (width) decoys from decoylist
  45. decoys, err := SelectDecoys(cjSession.Keys.SharedSecret, cjSession.V6Support.include, cjSession.Width)
  46. if err != nil {
  47. Logger().Warnf("%v failed to select decoys: %v", cjSession.IDString(), err)
  48. return nil, err
  49. }
  50. cjSession.RegDecoys = decoys
  51. phantom4, phantom6, err := SelectPhantom(cjSession.Keys.ConjureSeed, cjSession.V6Support.include)
  52. if err != nil {
  53. Logger().Warnf("%v failed to select Phantom: %v", cjSession.IDString(), err)
  54. return nil, err
  55. }
  56. //[reference] Prepare registration
  57. reg := &ConjureReg{
  58. sessionIDStr: cjSession.IDString(),
  59. keys: cjSession.Keys,
  60. stats: &pb.SessionStats{},
  61. phantom4: phantom4,
  62. phantom6: phantom6,
  63. v6Support: cjSession.V6Support.include,
  64. covertAddress: cjSession.CovertAddress,
  65. transport: cjSession.Transport,
  66. TcpDialer: cjSession.TcpDialer,
  67. useProxyHeader: cjSession.UseProxyHeader,
  68. }
  69. if r.TcpDialer != nil {
  70. reg.TcpDialer = r.TcpDialer
  71. }
  72. // //[TODO]{priority:later} How to pass context to multiple registration goroutines?
  73. if ctx == nil {
  74. ctx = context.Background()
  75. }
  76. width := uint(len(cjSession.RegDecoys))
  77. if width < cjSession.Width {
  78. Logger().Warnf("%v Using width %v (default %v)", cjSession.IDString(), width, cjSession.Width)
  79. }
  80. Logger().Debugf("%v Registration - v6:%v, covert:%v, phantoms:%v,[%v], width:%v, transport:%v",
  81. reg.sessionIDStr,
  82. reg.v6SupportStr(),
  83. reg.covertAddress,
  84. reg.phantom4.String(),
  85. reg.phantom6.String(),
  86. cjSession.Width,
  87. cjSession.Transport,
  88. )
  89. //[reference] Send registrations to each decoy
  90. dialErrors := make(chan error, width)
  91. for _, decoy := range cjSession.RegDecoys {
  92. Logger().Debugf("%v Sending Reg: %v, %v", cjSession.IDString(), decoy.GetHostname(), decoy.GetIpAddrStr())
  93. //decoyAddr := decoy.GetIpAddrStr()
  94. // [Psiphon]
  95. //
  96. // Workaround: reference and pass in reg.TcpDialer rather than wait
  97. // and reference it within reg.send in the goroutine. This allows
  98. // gotapdance users to clear and reset the TcpDialer field for cached
  99. // ConjureRegs without risking a race condition or nil pointer
  100. // dereference. These conditions otherwise arise as reg.send
  101. // goroutines can remain running, and reference reg.TcpDialer, after
  102. // Register returns -- the point at which gotapdance users may cache
  103. // the ConjureReg.
  104. go reg.send(ctx, decoy, reg.TcpDialer, dialErrors, cjSession.registrationCallback)
  105. }
  106. //[reference] Dial errors happen immediately so block until all N dials complete
  107. var unreachableCount uint = 0
  108. for err := range dialErrors {
  109. if err != nil {
  110. Logger().Debugf("%v %v", cjSession.IDString(), err)
  111. if dialErr, ok := err.(RegError); ok && dialErr.code == Unreachable {
  112. // If we failed because ipv6 network was unreachable try v4 only.
  113. unreachableCount++
  114. if unreachableCount < width {
  115. continue
  116. } else {
  117. break
  118. }
  119. }
  120. }
  121. //[reference] if we succeed or fail for any other reason then the network is reachable and we can continue
  122. break
  123. }
  124. //[reference] if ALL fail to dial return error (retry in parent if ipv6 unreachable)
  125. if unreachableCount == width {
  126. Logger().Debugf("%v NETWORK UNREACHABLE", cjSession.IDString())
  127. return nil, &RegError{code: Unreachable, msg: "All decoys failed to register -- Dial Unreachable"}
  128. }
  129. // randomized sleeping here to break the intraflow signal
  130. toSleep := reg.getRandomDuration(3000, 212, 3449)
  131. Logger().Debugf("%v Successfully sent registrations, sleeping for: %v", cjSession.IDString(), toSleep)
  132. sleepWithContext(ctx, toSleep)
  133. return reg, nil
  134. }
  135. // Registration strategy using a centralized REST API to
  136. // create registrations. Only the Endpoint need be specified;
  137. // the remaining fields are valid with their zero values and
  138. // provide the opportunity for additional control over the process.
  139. type APIRegistrar struct {
  140. // Endpoint to use in registration request
  141. Endpoint string
  142. // HTTP client to use in request
  143. Client *http.Client
  144. // Length of time to delay after confirming successful
  145. // registration before attempting a connection,
  146. // allowing for propagation throughout the stations.
  147. ConnectionDelay time.Duration
  148. // Maximum number of retries before giving up
  149. MaxRetries int
  150. // A secondary registration method to use on failure.
  151. // Because the API registration can give us definite
  152. // indication of a failure to register, this can be
  153. // used as a "backup" in the case of the API being
  154. // down or being blocked.
  155. //
  156. // If this field is nil, no secondary registration will
  157. // be attempted. If it is non-nil, after failing to register
  158. // (retrying MaxRetries times) we will fall back to
  159. // the Register method on this field.
  160. SecondaryRegistrar Registrar
  161. }
  162. func (r APIRegistrar) Register(cjSession *ConjureSession, ctx context.Context) (*ConjureReg, error) {
  163. Logger().Debugf("%v registering via APIRegistrar", cjSession.IDString())
  164. // TODO: this section is duplicated from DecoyRegistrar; consider consolidating
  165. phantom4, phantom6, err := SelectPhantom(cjSession.Keys.ConjureSeed, cjSession.V6Support.include)
  166. if err != nil {
  167. Logger().Warnf("%v failed to select Phantom: %v", cjSession.IDString(), err)
  168. return nil, err
  169. }
  170. // [reference] Prepare registration
  171. reg := &ConjureReg{
  172. sessionIDStr: cjSession.IDString(),
  173. keys: cjSession.Keys,
  174. stats: &pb.SessionStats{},
  175. phantom4: phantom4,
  176. phantom6: phantom6,
  177. v6Support: cjSession.V6Support.include,
  178. covertAddress: cjSession.CovertAddress,
  179. transport: cjSession.Transport,
  180. TcpDialer: cjSession.TcpDialer,
  181. useProxyHeader: cjSession.UseProxyHeader,
  182. }
  183. c2s := reg.generateClientToStation()
  184. protoPayload := pb.C2SWrapper{
  185. SharedSecret: cjSession.Keys.SharedSecret,
  186. RegistrationPayload: c2s,
  187. }
  188. payload, err := proto.Marshal(&protoPayload)
  189. if err != nil {
  190. Logger().Warnf("%v failed to marshal ClientToStation payload: %v", cjSession.IDString(), err)
  191. return nil, err
  192. }
  193. if r.Client == nil {
  194. // Transports should ideally be re-used for TCP connection pooling,
  195. // but each registration is most likely making precisely one request,
  196. // or if it's making more than one, is most likely due to an underlying
  197. // connection issue rather than an application-level error anyways.
  198. t := http.DefaultTransport.(*http.Transport).Clone()
  199. t.DialContext = reg.TcpDialer
  200. r.Client = &http.Client{Transport: t}
  201. }
  202. tries := 0
  203. for tries < r.MaxRetries+1 {
  204. tries++
  205. err = r.executeHTTPRequest(ctx, cjSession, payload)
  206. if err == nil {
  207. Logger().Debugf("%v API registration succeeded", cjSession.IDString())
  208. if r.ConnectionDelay != 0 {
  209. Logger().Debugf("%v sleeping for %v", cjSession.IDString(), r.ConnectionDelay)
  210. sleepWithContext(ctx, r.ConnectionDelay)
  211. }
  212. return reg, nil
  213. }
  214. Logger().Warnf("%v failed API registration, attempt %d/%d", cjSession.IDString(), tries, r.MaxRetries+1)
  215. }
  216. // If we make it here, we failed API registration
  217. Logger().Warnf("%v giving up on API registration", cjSession.IDString())
  218. if r.SecondaryRegistrar != nil {
  219. Logger().Debugf("%v trying secondary registration method", cjSession.IDString())
  220. return r.SecondaryRegistrar.Register(cjSession, ctx)
  221. }
  222. return nil, err
  223. }
  224. func (r APIRegistrar) executeHTTPRequest(ctx context.Context, cjSession *ConjureSession, payload []byte) error {
  225. req, err := http.NewRequestWithContext(ctx, "POST", r.Endpoint, bytes.NewReader(payload))
  226. if err != nil {
  227. Logger().Warnf("%v failed to create HTTP request to registration endpoint %s: %v", cjSession.IDString(), r.Endpoint, err)
  228. return err
  229. }
  230. resp, err := r.Client.Do(req)
  231. if err != nil {
  232. Logger().Warnf("%v failed to do HTTP request to registration endpoint %s: %v", cjSession.IDString(), r.Endpoint, err)
  233. return err
  234. }
  235. defer resp.Body.Close()
  236. if resp.StatusCode < 200 || resp.StatusCode >= 300 {
  237. Logger().Warnf("%v got non-success response code %d from registration endpoint %v", cjSession.IDString(), resp.StatusCode, r.Endpoint)
  238. return fmt.Errorf("non-success response code %d on %s", resp.StatusCode, r.Endpoint)
  239. }
  240. return nil
  241. }
  242. const (
  243. v4 uint = iota
  244. v6
  245. both
  246. )
  247. //[TODO]{priority:winter-break} make this not constant
  248. const defaultRegWidth = 5
  249. // DialConjureAddr - Perform Registration and Dial after creating a Conjure session from scratch
  250. func DialConjureAddr(ctx context.Context, address string, registrationMethod Registrar) (net.Conn, error) {
  251. cjSession := makeConjureSession(address, pb.TransportType_Min)
  252. return DialConjure(ctx, cjSession, registrationMethod)
  253. }
  254. // DialConjure - Perform Registration and Dial on an existing Conjure session
  255. func DialConjure(ctx context.Context, cjSession *ConjureSession, registrationMethod Registrar) (net.Conn, error) {
  256. if cjSession == nil {
  257. return nil, fmt.Errorf("No Session Provided")
  258. }
  259. cjSession.setV6Support(both)
  260. // Choose Phantom Address in Register depending on v6 support.
  261. registration, err := registrationMethod.Register(cjSession, ctx)
  262. if err != nil {
  263. Logger().Debugf("%v Failed to register: %v", cjSession.IDString(), err)
  264. return nil, err
  265. }
  266. Logger().Debugf("%v Attempting to Connect ...", cjSession.IDString())
  267. return registration.Connect(ctx)
  268. // return Connect(cjSession)
  269. }
  270. // // testV6 -- This is over simple and incomplete (currently unused)
  271. // // checking for unreachable alone does not account for local ipv6 addresses
  272. // // [TODO]{priority:winter-break} use getifaddr reverse bindings
  273. // func testV6() bool {
  274. // dialError := make(chan error, 1)
  275. // d := Assets().GetV6Decoy()
  276. // go func() {
  277. // conn, err := net.Dial("tcp", d.GetIpAddrStr())
  278. // if err != nil {
  279. // dialError <- err
  280. // return
  281. // }
  282. // conn.Close()
  283. // dialError <- nil
  284. // }()
  285. // time.Sleep(500 * time.Microsecond)
  286. // // The only error that would return before this is a network unreachable error
  287. // select {
  288. // case err := <-dialError:
  289. // Logger().Debugf("v6 unreachable received: %v", err)
  290. // return false
  291. // default:
  292. // return true
  293. // }
  294. // }
  295. // Connect - Dial the Phantom IP address after registration
  296. func Connect(ctx context.Context, reg *ConjureReg) (net.Conn, error) {
  297. return reg.Connect(ctx)
  298. }
  299. // ConjureSession - Create a session with details for registration and connection
  300. type ConjureSession struct {
  301. Keys *sharedKeys
  302. Width uint
  303. V6Support *V6
  304. UseProxyHeader bool
  305. SessionID uint64
  306. RegDecoys []*pb.TLSDecoySpec // pb.DecoyList
  307. Phantom *net.IP
  308. Transport pb.TransportType
  309. CovertAddress string
  310. // rtt uint // tracked in stats
  311. // THIS IS REQUIRED TO INTERFACE WITH PSIPHON ANDROID
  312. // we use their dialer to prevent connection loopback into our own proxy
  313. // connection when tunneling the whole device.
  314. TcpDialer func(context.Context, string, string) (net.Conn, error)
  315. // performance tracking
  316. stats *pb.SessionStats
  317. }
  318. func makeConjureSession(covert string, transport pb.TransportType) *ConjureSession {
  319. keys, err := generateSharedKeys(getStationKey())
  320. if err != nil {
  321. return nil
  322. }
  323. //[TODO]{priority:NOW} move v6support initialization to assets so it can be tracked across dials
  324. cjSession := &ConjureSession{
  325. Keys: keys,
  326. Width: defaultRegWidth,
  327. V6Support: &V6{support: true, include: both},
  328. UseProxyHeader: false,
  329. Transport: transport,
  330. CovertAddress: covert,
  331. SessionID: sessionsTotal.GetAndInc(),
  332. }
  333. sharedSecretStr := make([]byte, hex.EncodedLen(len(keys.SharedSecret)))
  334. hex.Encode(sharedSecretStr, keys.SharedSecret)
  335. Logger().Debugf("%v Shared Secret - %s", cjSession.IDString(), sharedSecretStr)
  336. Logger().Debugf("%v covert %s", cjSession.IDString(), covert)
  337. reprStr := make([]byte, hex.EncodedLen(len(keys.Representative)))
  338. hex.Encode(reprStr, keys.Representative)
  339. Logger().Debugf("%v Representative - %s", cjSession.IDString(), reprStr)
  340. return cjSession
  341. }
  342. // IDString - Get the ID string for the session
  343. func (cjSession *ConjureSession) IDString() string {
  344. if cjSession.Keys == nil || cjSession.Keys.SharedSecret == nil {
  345. return fmt.Sprintf("[%v-000000]", strconv.FormatUint(cjSession.SessionID, 10))
  346. }
  347. secret := make([]byte, hex.EncodedLen(len(cjSession.Keys.SharedSecret)))
  348. n := hex.Encode(secret, cjSession.Keys.SharedSecret)
  349. if n < 6 {
  350. return fmt.Sprintf("[%v-000000]", strconv.FormatUint(cjSession.SessionID, 10))
  351. }
  352. return fmt.Sprintf("[%v-%s]", strconv.FormatUint(cjSession.SessionID, 10), secret[:6])
  353. }
  354. // String - Print the string for debug and/or logging
  355. func (cjSession *ConjureSession) String() string {
  356. return cjSession.IDString()
  357. // expand for debug??
  358. }
  359. type resultTuple struct {
  360. conn net.Conn
  361. err error
  362. }
  363. // Simple type alias for brevity
  364. type dialFunc = func(ctx context.Context, network, addr string) (net.Conn, error)
  365. func (reg *ConjureReg) connect(ctx context.Context, addr string, dialer dialFunc) (net.Conn, error) {
  366. //[reference] Create Context with deadline
  367. deadline, deadlineAlreadySet := ctx.Deadline()
  368. if !deadlineAlreadySet {
  369. //[reference] randomized timeout to Dial dark decoy address
  370. deadline = time.Now().Add(reg.getRandomDuration(0, 1061*2, 1953*3))
  371. //[TODO]{priority:@sfrolov} explain these numbers and why they were chosen for the boundaries.
  372. }
  373. childCtx, childCancelFunc := context.WithDeadline(ctx, deadline)
  374. defer childCancelFunc()
  375. //[reference] Connect to Phantom Host
  376. phantomAddr := net.JoinHostPort(addr, "443")
  377. // conn, err := reg.TcpDialer(childCtx, "tcp", phantomAddr)
  378. return dialer(childCtx, "tcp", phantomAddr)
  379. }
  380. func (reg *ConjureReg) getFirstConnection(ctx context.Context, dialer dialFunc, phantoms []*net.IP) (net.Conn, error) {
  381. connChannel := make(chan resultTuple, len(phantoms))
  382. for _, p := range phantoms {
  383. if p == nil {
  384. continue
  385. }
  386. go func(phantom *net.IP) {
  387. conn, err := reg.connect(ctx, phantom.String(), dialer)
  388. if err != nil {
  389. Logger().Infof("%v failed to dial phantom %v: %v", reg.sessionIDStr, phantom.String(), err)
  390. connChannel <- resultTuple{nil, err}
  391. return
  392. }
  393. Logger().Infof("%v Connected to phantom %v using transport %d", reg.sessionIDStr, phantom.String(), reg.transport)
  394. connChannel <- resultTuple{conn, nil}
  395. }(p)
  396. }
  397. open := len(phantoms)
  398. for open > 0 {
  399. rt := <-connChannel
  400. if rt.err != nil {
  401. open--
  402. continue
  403. }
  404. // If we made it here we're returning the connection, so
  405. // set up a goroutine to close the others
  406. go func() {
  407. // Close all but one connection (the good one)
  408. for open > 1 {
  409. t := <-connChannel
  410. if t.err == nil {
  411. t.conn.Close()
  412. }
  413. open--
  414. }
  415. }()
  416. return rt.conn, nil
  417. }
  418. return nil, fmt.Errorf("no open connections")
  419. }
  420. // Connect - Use a registration (result of calling Register) to connect to a phantom
  421. // Note: This is hacky but should work for v4, v6, or both as any nil phantom addr will
  422. // return a dial error and be ignored.
  423. func (reg *ConjureReg) Connect(ctx context.Context) (net.Conn, error) {
  424. phantoms := []*net.IP{reg.phantom4, reg.phantom6}
  425. //[reference] Provide chosen transport to sent bytes (or connect) if necessary
  426. switch reg.transport {
  427. case pb.TransportType_Min:
  428. conn, err := reg.getFirstConnection(ctx, reg.TcpDialer, phantoms)
  429. if err != nil {
  430. Logger().Infof("%v failed to form phantom connection: %v", reg.sessionIDStr, err)
  431. return nil, err
  432. }
  433. // Send hmac(seed, str) bytes to indicate to station (min transport)
  434. connectTag := conjureHMAC(reg.keys.SharedSecret, "MinTrasportHMACString")
  435. conn.Write(connectTag)
  436. return conn, nil
  437. case pb.TransportType_Obfs4:
  438. args := pt.Args{}
  439. args.Add("node-id", reg.keys.Obfs4Keys.NodeID.Hex())
  440. args.Add("public-key", reg.keys.Obfs4Keys.PublicKey.Hex())
  441. args.Add("iat-mode", "1")
  442. Logger().Infof("%v node_id = %s; public key = %s", reg.sessionIDStr, reg.keys.Obfs4Keys.NodeID.Hex(), reg.keys.Obfs4Keys.PublicKey.Hex())
  443. t := obfs4.Transport{}
  444. c, err := t.ClientFactory("")
  445. if err != nil {
  446. Logger().Infof("%v failed to create client factory: %v", reg.sessionIDStr, err)
  447. return nil, err
  448. }
  449. parsedArgs, err := c.ParseArgs(&args)
  450. if err != nil {
  451. Logger().Infof("%v failed to parse obfs4 args: %v", reg.sessionIDStr, err)
  452. return nil, err
  453. }
  454. dialer := func(dialContext context.Context, network string, address string) (net.Conn, error) {
  455. d := func(network, address string) (net.Conn, error) { return reg.TcpDialer(dialContext, network, address) }
  456. return c.Dial("tcp", address, d, parsedArgs)
  457. }
  458. conn, err := reg.getFirstConnection(ctx, dialer, phantoms)
  459. if err != nil {
  460. Logger().Infof("%v failed to form obfs4 connection: %v", reg.sessionIDStr, err)
  461. return nil, err
  462. }
  463. return conn, err
  464. case pb.TransportType_Null:
  465. // Dial and do nothing to the connection before returning it to the user.
  466. return reg.getFirstConnection(ctx, reg.TcpDialer, phantoms)
  467. default:
  468. // If transport is unrecognized use min transport.
  469. return nil, fmt.Errorf("unknown transport")
  470. }
  471. }
  472. // ConjureReg - Registration structure created for each individual registration within a session.
  473. type ConjureReg struct {
  474. seed []byte
  475. sessionIDStr string
  476. phantom4 *net.IP
  477. phantom6 *net.IP
  478. useProxyHeader bool
  479. covertAddress string
  480. phantomSNI string
  481. v6Support uint
  482. transport pb.TransportType
  483. // THIS IS REQUIRED TO INTERFACE WITH PSIPHON ANDROID
  484. // we use their dialer to prevent connection loopback into our own proxy
  485. // connection when tunneling the whole device.
  486. TcpDialer func(context.Context, string, string) (net.Conn, error)
  487. stats *pb.SessionStats
  488. keys *sharedKeys
  489. m sync.Mutex
  490. }
  491. func (reg *ConjureReg) createRequest(tlsConn *tls.UConn, decoy *pb.TLSDecoySpec) ([]byte, error) {
  492. //[reference] generate and encrypt variable size payload
  493. vsp, err := reg.generateVSP()
  494. if err != nil {
  495. return nil, err
  496. }
  497. if len(vsp) > int(^uint16(0)) {
  498. return nil, fmt.Errorf("Variable-Size Payload exceeds %v", ^uint16(0))
  499. }
  500. encryptedVsp, err := aesGcmEncrypt(vsp, reg.keys.VspKey, reg.keys.VspIv)
  501. if err != nil {
  502. return nil, err
  503. }
  504. //[reference] generate and encrypt fixed size payload
  505. fsp := reg.generateFSP(uint16(len(encryptedVsp)))
  506. encryptedFsp, err := aesGcmEncrypt(fsp, reg.keys.FspKey, reg.keys.FspIv)
  507. if err != nil {
  508. return nil, err
  509. }
  510. var tag []byte // tag will be base-64 style encoded
  511. tag = append(encryptedVsp, reg.keys.Representative...)
  512. tag = append(tag, encryptedFsp...)
  513. httpRequest := generateHTTPRequestBeginning(decoy.GetHostname())
  514. keystreamOffset := len(httpRequest)
  515. keystreamSize := (len(tag)/3+1)*4 + keystreamOffset // we can't use first 2 bits of every byte
  516. wholeKeystream, err := tlsConn.GetOutKeystream(keystreamSize)
  517. if err != nil {
  518. return nil, err
  519. }
  520. keystreamAtTag := wholeKeystream[keystreamOffset:]
  521. httpRequest = append(httpRequest, reverseEncrypt(tag, keystreamAtTag)...)
  522. httpRequest = append(httpRequest, []byte("\r\n\r\n")...)
  523. return httpRequest, nil
  524. }
  525. // Being called in parallel -> no changes to ConjureReg allowed in this function
  526. func (reg *ConjureReg) send(ctx context.Context, decoy *pb.TLSDecoySpec, dialer dialFunc, dialError chan error, callback func(*ConjureReg)) {
  527. deadline, deadlineAlreadySet := ctx.Deadline()
  528. if !deadlineAlreadySet {
  529. deadline = time.Now().Add(getRandomDuration(deadlineTCPtoDecoyMin, deadlineTCPtoDecoyMax))
  530. }
  531. childCtx, childCancelFunc := context.WithDeadline(ctx, deadline)
  532. defer childCancelFunc()
  533. //[reference] TCP to decoy
  534. tcpToDecoyStartTs := time.Now()
  535. //[Note] decoy.GetIpAddrStr() will get only v4 addr if a decoy has both
  536. dialConn, err := dialer(childCtx, "tcp", decoy.GetIpAddrStr())
  537. reg.setTCPToDecoy(durationToU32ptrMs(time.Since(tcpToDecoyStartTs)))
  538. if err != nil {
  539. if opErr, ok := err.(*net.OpError); ok && opErr.Err.Error() == "connect: network is unreachable" {
  540. dialError <- RegError{msg: err.Error(), code: Unreachable}
  541. return
  542. }
  543. dialError <- err
  544. return
  545. }
  546. //[reference] connection stats tracking
  547. rtt := rttInt(uint32(time.Since(tcpToDecoyStartTs).Milliseconds()))
  548. delay := getRandomDuration(1061*rtt*2, 1953*rtt*3) //[TODO]{priority:@sfrolov} why these values??
  549. TLSDeadline := time.Now().Add(delay)
  550. tlsToDecoyStartTs := time.Now()
  551. tlsConn, err := reg.createTLSConn(dialConn, decoy.GetIpAddrStr(), decoy.GetHostname(), TLSDeadline)
  552. if err != nil {
  553. dialConn.Close()
  554. msg := fmt.Sprintf("%v - %v createConn: %v", decoy.GetHostname(), decoy.GetIpAddrStr(), err.Error())
  555. dialError <- RegError{msg: msg, code: TLSError}
  556. return
  557. }
  558. reg.setTLSToDecoy(durationToU32ptrMs(time.Since(tlsToDecoyStartTs)))
  559. //[reference] Create the HTTP request for the registration
  560. httpRequest, err := reg.createRequest(tlsConn, decoy)
  561. if err != nil {
  562. msg := fmt.Sprintf("%v - %v createReq: %v", decoy.GetHostname(), decoy.GetIpAddrStr(), err.Error())
  563. dialError <- RegError{msg: msg, code: TLSError}
  564. return
  565. }
  566. //[reference] Write reg into conn
  567. _, err = tlsConn.Write(httpRequest)
  568. if err != nil {
  569. // // This will not get printed because it is executed in a goroutine.
  570. // Logger().Errorf("%v - %v Could not send Conjure registration request, error: %v", decoy.GetHostname(), decoy.GetIpAddrStr(), err.Error())
  571. tlsConn.Close()
  572. msg := fmt.Sprintf("%v - %v Write: %v", decoy.GetHostname(), decoy.GetIpAddrStr(), err.Error())
  573. dialError <- RegError{msg: msg, code: TLSError}
  574. return
  575. }
  576. dialError <- nil
  577. readAndClose(dialConn, time.Second*15)
  578. callback(reg)
  579. }
  580. func (reg *ConjureReg) createTLSConn(dialConn net.Conn, address string, hostname string, deadline time.Time) (*tls.UConn, error) {
  581. var err error
  582. //[reference] TLS to Decoy
  583. config := tls.Config{ServerName: hostname}
  584. if config.ServerName == "" {
  585. // if SNI is unset -- try IP
  586. config.ServerName, _, err = net.SplitHostPort(address)
  587. if err != nil {
  588. return nil, err
  589. }
  590. Logger().Debugf("%v SNI was nil. Setting it to %v ", reg.sessionIDStr, config.ServerName)
  591. }
  592. //[TODO]{priority:medium} parroting Chrome 62 ClientHello -- parrot newer.
  593. tlsConn := tls.UClient(dialConn, &config, tls.HelloChrome_62)
  594. err = tlsConn.BuildHandshakeState()
  595. if err != nil {
  596. return nil, err
  597. }
  598. err = tlsConn.MarshalClientHello()
  599. if err != nil {
  600. return nil, err
  601. }
  602. tlsConn.SetDeadline(deadline)
  603. err = tlsConn.Handshake()
  604. if err != nil {
  605. return nil, err
  606. }
  607. return tlsConn, nil
  608. }
  609. func (reg *ConjureReg) setTCPToDecoy(tcprtt *uint32) {
  610. reg.m.Lock()
  611. defer reg.m.Unlock()
  612. if reg.stats == nil {
  613. reg.stats = &pb.SessionStats{}
  614. }
  615. reg.stats.TcpToDecoy = tcprtt
  616. }
  617. func (reg *ConjureReg) setTLSToDecoy(tlsrtt *uint32) {
  618. reg.m.Lock()
  619. defer reg.m.Unlock()
  620. if reg.stats == nil {
  621. reg.stats = &pb.SessionStats{}
  622. }
  623. reg.stats.TlsToDecoy = tlsrtt
  624. }
  625. func (reg *ConjureReg) getPbTransport() pb.TransportType {
  626. return pb.TransportType(reg.transport)
  627. }
  628. func (reg *ConjureReg) generateFlags() *pb.RegistrationFlags {
  629. flags := &pb.RegistrationFlags{}
  630. mask := default_flags
  631. if reg.useProxyHeader {
  632. mask |= tdFlagProxyHeader
  633. }
  634. uploadOnly := mask&tdFlagUploadOnly == tdFlagUploadOnly
  635. proxy := mask&tdFlagProxyHeader == tdFlagProxyHeader
  636. til := mask&tdFlagUseTIL == tdFlagUseTIL
  637. flags.UploadOnly = &uploadOnly
  638. flags.ProxyHeader = &proxy
  639. flags.Use_TIL = &til
  640. return flags
  641. }
  642. func (reg *ConjureReg) generateClientToStation() *pb.ClientToStation {
  643. var covert *string
  644. if len(reg.covertAddress) > 0 {
  645. //[TODO]{priority:medium} this isn't the correct place to deal with signaling to the station
  646. //transition = pb.C2S_Transition_C2S_SESSION_COVERT_INIT
  647. covert = &reg.covertAddress
  648. }
  649. //[reference] Generate ClientToStation protobuf
  650. // transition := pb.C2S_Transition_C2S_SESSION_INIT
  651. currentGen := Assets().GetGeneration()
  652. transport := reg.getPbTransport()
  653. initProto := &pb.ClientToStation{
  654. CovertAddress: covert,
  655. DecoyListGeneration: &currentGen,
  656. V6Support: reg.getV6Support(),
  657. V4Support: reg.getV4Support(),
  658. Transport: &transport,
  659. Flags: reg.generateFlags(),
  660. // StateTransition: &transition,
  661. //[TODO]{priority:medium} specify width in C2S because different width might
  662. // be useful in different regions (constant for now.)
  663. }
  664. if len(reg.phantomSNI) > 0 {
  665. initProto.MaskedDecoyServerName = &reg.phantomSNI
  666. }
  667. for (proto.Size(initProto)+AES_GCM_TAG_SIZE)%3 != 0 {
  668. initProto.Padding = append(initProto.Padding, byte(0))
  669. }
  670. return initProto
  671. }
  672. func (reg *ConjureReg) generateVSP() ([]byte, error) {
  673. //[reference] Marshal ClientToStation protobuf
  674. return proto.Marshal(reg.generateClientToStation())
  675. }
  676. func (reg *ConjureReg) generateFSP(espSize uint16) []byte {
  677. buf := make([]byte, 6)
  678. binary.BigEndian.PutUint16(buf[0:2], espSize)
  679. return buf
  680. }
  681. func (reg *ConjureReg) getV4Support() *bool {
  682. // for now return true and register both
  683. support := true
  684. if reg.v6Support == v6 {
  685. support = false
  686. }
  687. return &support
  688. }
  689. func (reg *ConjureReg) getV6Support() *bool {
  690. support := true
  691. if reg.v6Support == v4 {
  692. support = false
  693. }
  694. return &support
  695. }
  696. func (reg *ConjureReg) v6SupportStr() string {
  697. switch reg.v6Support {
  698. case both:
  699. return "Both"
  700. case v4:
  701. return "V4"
  702. case v6:
  703. return "V6"
  704. default:
  705. return "unknown"
  706. }
  707. }
  708. func (reg *ConjureReg) digestStats() string {
  709. //[TODO]{priority:eventually} add decoy details to digest
  710. if reg == nil || reg.stats == nil {
  711. return fmt.Sprint("{result:\"no stats tracked\"}")
  712. }
  713. reg.m.Lock()
  714. defer reg.m.Unlock()
  715. return fmt.Sprintf("{result:\"success\", tcp_to_decoy:%v, tls_to_decoy:%v, total_time_to_connect:%v}",
  716. reg.stats.GetTcpToDecoy(),
  717. reg.stats.GetTlsToDecoy(),
  718. reg.stats.GetTotalTimeToConnect())
  719. }
  720. func (reg *ConjureReg) getRandomDuration(base, min, max int) time.Duration {
  721. addon := getRandInt(min, max) / 1000 // why this min and max???
  722. rtt := rttInt(reg.getTcpToDecoy())
  723. return time.Millisecond * time.Duration(base+rtt*addon)
  724. }
  725. func (reg *ConjureReg) getTcpToDecoy() uint32 {
  726. reg.m.Lock()
  727. defer reg.m.Unlock()
  728. if reg != nil {
  729. if reg.stats != nil {
  730. return reg.stats.GetTcpToDecoy()
  731. }
  732. }
  733. return 0
  734. }
  735. func (cjSession *ConjureSession) setV6Support(support uint) {
  736. switch support {
  737. case v4:
  738. cjSession.V6Support.support = false
  739. cjSession.V6Support.include = v4
  740. case v6:
  741. cjSession.V6Support.support = true
  742. cjSession.V6Support.include = v6
  743. case both:
  744. cjSession.V6Support.support = true
  745. cjSession.V6Support.include = both
  746. default:
  747. cjSession.V6Support.support = true
  748. cjSession.V6Support.include = v6
  749. }
  750. }
  751. // When a registration send goroutine finishes it will call this and log
  752. // session stats and/or errors.
  753. func (cjSession *ConjureSession) registrationCallback(reg *ConjureReg) {
  754. //[TODO]{priority:NOW}
  755. Logger().Infof("%v %v", cjSession.IDString(), reg.digestStats())
  756. }
  757. func (cjSession *ConjureSession) getRandomDuration(base, min, max int) time.Duration {
  758. addon := getRandInt(min, max) / 1000 // why this min and max???
  759. rtt := rttInt(cjSession.getTcpToDecoy())
  760. return time.Millisecond * time.Duration(base+rtt*addon)
  761. }
  762. func (cjSession *ConjureSession) getTcpToDecoy() uint32 {
  763. if cjSession != nil {
  764. if cjSession.stats != nil {
  765. return cjSession.stats.GetTcpToDecoy()
  766. }
  767. }
  768. return 0
  769. }
  770. func sleepWithContext(ctx context.Context, duration time.Duration) {
  771. timer := time.NewTimer(duration)
  772. defer timer.Stop()
  773. select {
  774. case <-timer.C:
  775. case <-ctx.Done():
  776. }
  777. }
  778. func rttInt(millis uint32) int {
  779. defaultValue := 300
  780. if millis == 0 {
  781. return defaultValue
  782. }
  783. return int(millis)
  784. }
  785. // SelectDecoys - Get an array of `width` decoys to be used for registration
  786. func SelectDecoys(sharedSecret []byte, version uint, width uint) ([]*pb.TLSDecoySpec, error) {
  787. //[reference] prune to v6 only decoys if useV6 is true
  788. var allDecoys []*pb.TLSDecoySpec
  789. switch version {
  790. case v6:
  791. allDecoys = Assets().GetV6Decoys()
  792. case v4:
  793. allDecoys = Assets().GetV4Decoys()
  794. case both:
  795. allDecoys = Assets().GetAllDecoys()
  796. default:
  797. allDecoys = Assets().GetAllDecoys()
  798. }
  799. if len(allDecoys) == 0 {
  800. return nil, fmt.Errorf("no decoys")
  801. }
  802. decoys := make([]*pb.TLSDecoySpec, width)
  803. numDecoys := big.NewInt(int64(len(allDecoys)))
  804. hmacInt := new(big.Int)
  805. idx := new(big.Int)
  806. //[reference] select decoys
  807. for i := uint(0); i < width; i++ {
  808. macString := fmt.Sprintf("registrationdecoy%d", i)
  809. hmac := conjureHMAC(sharedSecret, macString)
  810. hmacInt = hmacInt.SetBytes(hmac[:8])
  811. hmacInt.SetBytes(hmac)
  812. hmacInt.Abs(hmacInt)
  813. idx.Mod(hmacInt, numDecoys)
  814. decoys[i] = allDecoys[int(idx.Int64())]
  815. }
  816. return decoys, nil
  817. }
  818. // var phantomSubnets = []conjurePhantomSubnet{
  819. // {subnet: "192.122.190.0/24", weight: 90.0},
  820. // {subnet: "2001:48a8:687f:1::/64", weight: 90.0},
  821. // {subnet: "141.219.0.0/16", weight: 10.0},
  822. // {subnet: "35.8.0.0/16", weight: 10.0},
  823. // }
  824. // SelectPhantom - select one phantom IP address based on shared secret
  825. func SelectPhantom(seed []byte, support uint) (*net.IP, *net.IP, error) {
  826. phantomSubnets := Assets().GetPhantomSubnets()
  827. switch support {
  828. case v4:
  829. phantomIPv4, err := ps.SelectPhantom(seed, phantomSubnets, ps.V4Only, true)
  830. if err != nil {
  831. return nil, nil, err
  832. }
  833. return phantomIPv4, nil, nil
  834. case v6:
  835. phantomIPv6, err := ps.SelectPhantom(seed, phantomSubnets, ps.V6Only, true)
  836. if err != nil {
  837. return nil, nil, err
  838. }
  839. return nil, phantomIPv6, nil
  840. case both:
  841. phantomIPv4, err := ps.SelectPhantom(seed, phantomSubnets, ps.V4Only, true)
  842. if err != nil {
  843. return nil, nil, err
  844. }
  845. phantomIPv6, err := ps.SelectPhantom(seed, phantomSubnets, ps.V6Only, true)
  846. if err != nil {
  847. return nil, nil, err
  848. }
  849. return phantomIPv4, phantomIPv6, nil
  850. default:
  851. return nil, nil, fmt.Errorf("unknown v4/v6 support")
  852. }
  853. }
  854. func getStationKey() [32]byte {
  855. return *Assets().GetConjurePubkey()
  856. }
  857. type Obfs4Keys struct {
  858. PrivateKey *ntor.PrivateKey
  859. PublicKey *ntor.PublicKey
  860. NodeID *ntor.NodeID
  861. }
  862. func generateObfs4Keys(rand io.Reader) (Obfs4Keys, error) {
  863. keys := Obfs4Keys{
  864. PrivateKey: new(ntor.PrivateKey),
  865. PublicKey: new(ntor.PublicKey),
  866. NodeID: new(ntor.NodeID),
  867. }
  868. _, err := rand.Read(keys.PrivateKey[:])
  869. if err != nil {
  870. return keys, err
  871. }
  872. keys.PrivateKey[0] &= 248
  873. keys.PrivateKey[31] &= 127
  874. keys.PrivateKey[31] |= 64
  875. pub, err := curve25519.X25519(keys.PrivateKey[:], curve25519.Basepoint)
  876. if err != nil {
  877. return keys, err
  878. }
  879. copy(keys.PublicKey[:], pub)
  880. _, err = rand.Read(keys.NodeID[:])
  881. return keys, err
  882. }
  883. type sharedKeys struct {
  884. SharedSecret, Representative []byte
  885. FspKey, FspIv, VspKey, VspIv, NewMasterSecret, ConjureSeed []byte
  886. Obfs4Keys Obfs4Keys
  887. }
  888. func generateSharedKeys(pubkey [32]byte) (*sharedKeys, error) {
  889. sharedSecret, representative, err := generateEligatorTransformedKey(pubkey[:])
  890. if err != nil {
  891. return nil, err
  892. }
  893. tdHkdf := hkdf.New(sha256.New, sharedSecret, []byte("conjureconjureconjureconjure"), nil)
  894. keys := &sharedKeys{
  895. SharedSecret: sharedSecret,
  896. Representative: representative,
  897. FspKey: make([]byte, 16),
  898. FspIv: make([]byte, 12),
  899. VspKey: make([]byte, 16),
  900. VspIv: make([]byte, 12),
  901. NewMasterSecret: make([]byte, 48),
  902. ConjureSeed: make([]byte, 16),
  903. }
  904. if _, err := tdHkdf.Read(keys.FspKey); err != nil {
  905. return keys, err
  906. }
  907. if _, err := tdHkdf.Read(keys.FspIv); err != nil {
  908. return keys, err
  909. }
  910. if _, err := tdHkdf.Read(keys.VspKey); err != nil {
  911. return keys, err
  912. }
  913. if _, err := tdHkdf.Read(keys.VspIv); err != nil {
  914. return keys, err
  915. }
  916. if _, err := tdHkdf.Read(keys.NewMasterSecret); err != nil {
  917. return keys, err
  918. }
  919. if _, err := tdHkdf.Read(keys.ConjureSeed); err != nil {
  920. return keys, err
  921. }
  922. keys.Obfs4Keys, err = generateObfs4Keys(tdHkdf)
  923. return keys, err
  924. }
  925. //
  926. func conjureHMAC(key []byte, str string) []byte {
  927. hash := hmac.New(sha256.New, key)
  928. hash.Write([]byte(str))
  929. return hash.Sum(nil)
  930. }
  931. // RegError - Registration Error passed during registration to indicate failure mode
  932. type RegError struct {
  933. code uint
  934. msg string
  935. }
  936. func (err RegError) Error() string {
  937. return fmt.Sprintf("Registration Error [%v]: %v", err.CodeStr(), err.msg)
  938. }
  939. // CodeStr - Get desctriptor associated with error code
  940. func (err RegError) CodeStr() string {
  941. switch err.code {
  942. case Unreachable:
  943. return "UNREACHABLE"
  944. case DialFailure:
  945. return "DIAL_FAILURE"
  946. case NotImplemented:
  947. return "NOT_IMPLEMENTED"
  948. case TLSError:
  949. return "TLS_ERROR"
  950. default:
  951. return "UNKNOWN"
  952. }
  953. }
  954. const (
  955. // Unreachable -Dial Error Unreachable -- likely network unavailable (i.e. ipv6 error)
  956. Unreachable = iota
  957. // DialFailure - Dial Error Other than unreachable
  958. DialFailure
  959. // NotImplemented - Related Function Not Implemented
  960. NotImplemented
  961. // TLS Error (Expired, Wrong-Host, Untrusted-Root, ...)
  962. TLSError
  963. // Unknown - Error occurred without obvious explanation
  964. Unknown
  965. )