ticket.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tls
  5. import (
  6. "bytes"
  7. "crypto/aes"
  8. "crypto/cipher"
  9. "crypto/hmac"
  10. "crypto/sha256"
  11. "crypto/subtle"
  12. "errors"
  13. "io"
  14. // [Psiphon]
  15. "crypto/rand"
  16. "crypto/x509"
  17. "math/big"
  18. math_rand "math/rand"
  19. )
  20. // [Psiphon]
  21. var obfuscateSessionTickets = true
  22. // A SessionTicketSealer provides a way to securely encapsulate
  23. // session state for storage on the client. All methods are safe for
  24. // concurrent use.
  25. type SessionTicketSealer interface {
  26. // Seal returns a session ticket value that can be later passed to Unseal
  27. // to recover the content, usually by encrypting it. The ticket will be sent
  28. // to the client to be stored, and will be sent back in plaintext, so it can
  29. // be read and modified by an attacker.
  30. Seal(cs *ConnectionState, content []byte) (ticket []byte, err error)
  31. // Unseal returns a session ticket contents. The ticket can't be safely
  32. // assumed to have been generated by Seal.
  33. // If unable to unseal the ticket, the connection will proceed with a
  34. // complete handshake.
  35. Unseal(chi *ClientHelloInfo, ticket []byte) (content []byte, success bool)
  36. }
  37. // sessionState contains the information that is serialized into a session
  38. // ticket in order to later resume a connection.
  39. type sessionState struct {
  40. vers uint16
  41. cipherSuite uint16
  42. usedEMS bool
  43. masterSecret []byte
  44. certificates [][]byte
  45. // usedOldKey is true if the ticket from which this session came from
  46. // was encrypted with an older key and thus should be refreshed.
  47. usedOldKey bool
  48. }
  49. func (s *sessionState) equal(i interface{}) bool {
  50. s1, ok := i.(*sessionState)
  51. if !ok {
  52. return false
  53. }
  54. if s.vers != s1.vers ||
  55. s.usedEMS != s1.usedEMS ||
  56. s.cipherSuite != s1.cipherSuite ||
  57. !bytes.Equal(s.masterSecret, s1.masterSecret) {
  58. return false
  59. }
  60. if len(s.certificates) != len(s1.certificates) {
  61. return false
  62. }
  63. for i := range s.certificates {
  64. if !bytes.Equal(s.certificates[i], s1.certificates[i]) {
  65. return false
  66. }
  67. }
  68. return true
  69. }
  70. func (s *sessionState) marshal() []byte {
  71. length := 2 + 2 + 2 + len(s.masterSecret) + 2
  72. for _, cert := range s.certificates {
  73. length += 4 + len(cert)
  74. }
  75. // [Psiphon]
  76. // Pad golang TLS session ticket to a more typical size.
  77. if obfuscateSessionTickets {
  78. paddedSizes := []int{160, 176, 192, 208, 218, 224, 240, 255}
  79. initialSize := 120
  80. randomInt, err := rand.Int(rand.Reader, big.NewInt(int64(len(paddedSizes))))
  81. index := 0
  82. if err == nil {
  83. index = int(randomInt.Int64())
  84. } else {
  85. index = math_rand.Intn(len(paddedSizes))
  86. }
  87. paddingSize := paddedSizes[index] - initialSize
  88. length += paddingSize
  89. }
  90. ret := make([]byte, length)
  91. x := ret
  92. was_used := byte(0)
  93. if s.usedEMS {
  94. was_used = byte(0x80)
  95. }
  96. x[0] = byte(s.vers>>8) | byte(was_used)
  97. x[1] = byte(s.vers)
  98. x[2] = byte(s.cipherSuite >> 8)
  99. x[3] = byte(s.cipherSuite)
  100. x[4] = byte(len(s.masterSecret) >> 8)
  101. x[5] = byte(len(s.masterSecret))
  102. x = x[6:]
  103. copy(x, s.masterSecret)
  104. x = x[len(s.masterSecret):]
  105. x[0] = byte(len(s.certificates) >> 8)
  106. x[1] = byte(len(s.certificates))
  107. x = x[2:]
  108. for _, cert := range s.certificates {
  109. x[0] = byte(len(cert) >> 24)
  110. x[1] = byte(len(cert) >> 16)
  111. x[2] = byte(len(cert) >> 8)
  112. x[3] = byte(len(cert))
  113. copy(x[4:], cert)
  114. x = x[4+len(cert):]
  115. }
  116. return ret
  117. }
  118. func (s *sessionState) unmarshal(data []byte) alert {
  119. if len(data) < 8 {
  120. return alertDecodeError
  121. }
  122. s.vers = (uint16(data[0])<<8 | uint16(data[1])) & 0x7fff
  123. s.cipherSuite = uint16(data[2])<<8 | uint16(data[3])
  124. s.usedEMS = (data[0] & 0x80) == 0x80
  125. masterSecretLen := int(data[4])<<8 | int(data[5])
  126. data = data[6:]
  127. if len(data) < masterSecretLen {
  128. return alertDecodeError
  129. }
  130. s.masterSecret = data[:masterSecretLen]
  131. data = data[masterSecretLen:]
  132. if len(data) < 2 {
  133. return alertDecodeError
  134. }
  135. numCerts := int(data[0])<<8 | int(data[1])
  136. data = data[2:]
  137. s.certificates = make([][]byte, numCerts)
  138. for i := range s.certificates {
  139. if len(data) < 4 {
  140. return alertDecodeError
  141. }
  142. certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3])
  143. data = data[4:]
  144. if certLen < 0 {
  145. return alertDecodeError
  146. }
  147. if len(data) < certLen {
  148. return alertDecodeError
  149. }
  150. s.certificates[i] = data[:certLen]
  151. data = data[certLen:]
  152. }
  153. // [Psiphon]
  154. // Ignore padding for obfuscated session tickets
  155. //if len(data) != 0 {
  156. // return alertDecodeError
  157. //}
  158. return alertSuccess
  159. }
  160. // [Psiphon]
  161. type ObfuscatedClientSessionState struct {
  162. SessionTicket []uint8
  163. Vers uint16
  164. CipherSuite uint16
  165. MasterSecret []byte
  166. ServerCertificates []*x509.Certificate
  167. VerifiedChains [][]*x509.Certificate
  168. UseEMS bool
  169. }
  170. var obfuscatedSessionTicketCipherSuite = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  171. // [Psiphon]
  172. // NewObfuscatedClientSessionState produces obfuscated session tickets.
  173. //
  174. // Obfuscated Session Tickets
  175. //
  176. // Obfuscated session tickets is a network traffic obfuscation protocol that appears
  177. // to be valid TLS using session tickets. The client actually generates the session
  178. // ticket and encrypts it with a shared secret, enabling a TLS session that entirely
  179. // skips the most fingerprintable aspects of TLS.
  180. // The scheme is described here:
  181. // https://lists.torproject.org/pipermail/tor-dev/2016-September/011354.html
  182. //
  183. // Circumvention notes:
  184. // - TLS session ticket implementations are widespread:
  185. // https://istlsfastyet.com/#cdn-paas.
  186. // - An adversary cannot easily block session ticket capability, as this requires
  187. // a downgrade attack against TLS.
  188. // - Anti-probing defence is provided, as the adversary must use the correct obfuscation
  189. // shared secret to form valid obfuscation session ticket; otherwise server offers
  190. // standard session tickets.
  191. // - Limitation: an adversary with the obfuscation shared secret can decrypt the session
  192. // ticket and observe the plaintext traffic. It's assumed that the adversary will not
  193. // learn the obfuscated shared secret without also learning the address of the TLS
  194. // server and blocking it anyway; it's also assumed that the TLS payload is not
  195. // plaintext but is protected with some other security layer (e.g., SSH).
  196. //
  197. // Implementation notes:
  198. // - The TLS ClientHello includes an SNI field, even when using session tickets, so
  199. // the client should populate the ServerName.
  200. // - Server should set its SetSessionTicketKeys with first a standard key, followed by
  201. // the obfuscation shared secret.
  202. // - Since the client creates the session ticket, it selects parameters that were not
  203. // negotiated with the server, such as the cipher suite. It's implicitly assumed that
  204. // the server can support the selected parameters.
  205. // - Obfuscated session tickets are not supported for TLS 1.3 _clients_, which use a
  206. // distinct scheme. Obfuscated session ticket support in this package is intended to
  207. // support TLS 1.2 clients.
  208. //
  209. func NewObfuscatedClientSessionState(sharedSecret [32]byte) (*ObfuscatedClientSessionState, error) {
  210. // Create a session ticket that wasn't actually issued by the server.
  211. vers := uint16(VersionTLS12)
  212. cipherSuite := obfuscatedSessionTicketCipherSuite
  213. masterSecret := make([]byte, masterSecretLength)
  214. _, err := rand.Read(masterSecret)
  215. if err != nil {
  216. return nil, err
  217. }
  218. serverState := &sessionState{
  219. vers: vers,
  220. cipherSuite: cipherSuite,
  221. masterSecret: masterSecret,
  222. certificates: nil,
  223. }
  224. c := &Conn{
  225. config: &Config{
  226. sessionTicketKeys: []ticketKey{ticketKeyFromBytes(sharedSecret)},
  227. },
  228. }
  229. sessionTicket, err := c.encryptTicket(serverState.marshal())
  230. if err != nil {
  231. return nil, err
  232. }
  233. // ObfuscatedClientSessionState fields are used to construct
  234. // ClientSessionState objects for use in ClientSessionCaches. The client will
  235. // use this cache to pretend it got that session ticket from the server.
  236. clientState := &ObfuscatedClientSessionState{
  237. SessionTicket: sessionTicket,
  238. Vers: vers,
  239. CipherSuite: cipherSuite,
  240. MasterSecret: masterSecret,
  241. }
  242. return clientState, nil
  243. }
  244. func ContainsObfuscatedSessionTicketCipherSuite(cipherSuites []uint16) bool {
  245. for _, cipherSuite := range cipherSuites {
  246. if cipherSuite == obfuscatedSessionTicketCipherSuite {
  247. return true
  248. }
  249. }
  250. return false
  251. }
  252. type sessionState13 struct {
  253. vers uint16
  254. suite uint16
  255. ageAdd uint32
  256. createdAt uint64
  257. maxEarlyDataLen uint32
  258. pskSecret []byte
  259. alpnProtocol string
  260. SNI string
  261. }
  262. func (s *sessionState13) equal(i interface{}) bool {
  263. s1, ok := i.(*sessionState13)
  264. if !ok {
  265. return false
  266. }
  267. return s.vers == s1.vers &&
  268. s.suite == s1.suite &&
  269. s.ageAdd == s1.ageAdd &&
  270. s.createdAt == s1.createdAt &&
  271. s.maxEarlyDataLen == s1.maxEarlyDataLen &&
  272. subtle.ConstantTimeCompare(s.pskSecret, s1.pskSecret) == 1 &&
  273. s.alpnProtocol == s1.alpnProtocol &&
  274. s.SNI == s1.SNI
  275. }
  276. func (s *sessionState13) marshal() []byte {
  277. length := 2 + 2 + 4 + 8 + 4 + 2 + len(s.pskSecret) + 2 + len(s.alpnProtocol) + 2 + len(s.SNI)
  278. x := make([]byte, length)
  279. x[0] = byte(s.vers >> 8)
  280. x[1] = byte(s.vers)
  281. x[2] = byte(s.suite >> 8)
  282. x[3] = byte(s.suite)
  283. x[4] = byte(s.ageAdd >> 24)
  284. x[5] = byte(s.ageAdd >> 16)
  285. x[6] = byte(s.ageAdd >> 8)
  286. x[7] = byte(s.ageAdd)
  287. x[8] = byte(s.createdAt >> 56)
  288. x[9] = byte(s.createdAt >> 48)
  289. x[10] = byte(s.createdAt >> 40)
  290. x[11] = byte(s.createdAt >> 32)
  291. x[12] = byte(s.createdAt >> 24)
  292. x[13] = byte(s.createdAt >> 16)
  293. x[14] = byte(s.createdAt >> 8)
  294. x[15] = byte(s.createdAt)
  295. x[16] = byte(s.maxEarlyDataLen >> 24)
  296. x[17] = byte(s.maxEarlyDataLen >> 16)
  297. x[18] = byte(s.maxEarlyDataLen >> 8)
  298. x[19] = byte(s.maxEarlyDataLen)
  299. x[20] = byte(len(s.pskSecret) >> 8)
  300. x[21] = byte(len(s.pskSecret))
  301. copy(x[22:], s.pskSecret)
  302. z := x[22+len(s.pskSecret):]
  303. z[0] = byte(len(s.alpnProtocol) >> 8)
  304. z[1] = byte(len(s.alpnProtocol))
  305. copy(z[2:], s.alpnProtocol)
  306. z = z[2+len(s.alpnProtocol):]
  307. z[0] = byte(len(s.SNI) >> 8)
  308. z[1] = byte(len(s.SNI))
  309. copy(z[2:], s.SNI)
  310. return x
  311. }
  312. func (s *sessionState13) unmarshal(data []byte) alert {
  313. if len(data) < 24 {
  314. return alertDecodeError
  315. }
  316. s.vers = uint16(data[0])<<8 | uint16(data[1])
  317. s.suite = uint16(data[2])<<8 | uint16(data[3])
  318. s.ageAdd = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
  319. s.createdAt = uint64(data[8])<<56 | uint64(data[9])<<48 | uint64(data[10])<<40 | uint64(data[11])<<32 |
  320. uint64(data[12])<<24 | uint64(data[13])<<16 | uint64(data[14])<<8 | uint64(data[15])
  321. s.maxEarlyDataLen = uint32(data[16])<<24 | uint32(data[17])<<16 | uint32(data[18])<<8 | uint32(data[19])
  322. l := int(data[20])<<8 | int(data[21])
  323. if len(data) < 22+l+2 {
  324. return alertDecodeError
  325. }
  326. s.pskSecret = data[22 : 22+l]
  327. z := data[22+l:]
  328. l = int(z[0])<<8 | int(z[1])
  329. if len(z) < 2+l+2 {
  330. return alertDecodeError
  331. }
  332. s.alpnProtocol = string(z[2 : 2+l])
  333. z = z[2+l:]
  334. l = int(z[0])<<8 | int(z[1])
  335. if len(z) != 2+l {
  336. return alertDecodeError
  337. }
  338. s.SNI = string(z[2 : 2+l])
  339. return alertSuccess
  340. }
  341. func (c *Conn) encryptTicket(serialized []byte) ([]byte, error) {
  342. encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(serialized)+sha256.Size)
  343. keyName := encrypted[:ticketKeyNameLen]
  344. iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
  345. macBytes := encrypted[len(encrypted)-sha256.Size:]
  346. if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
  347. return nil, err
  348. }
  349. key := c.config.ticketKeys()[0]
  350. copy(keyName, key.keyName[:])
  351. block, err := aes.NewCipher(key.aesKey[:])
  352. if err != nil {
  353. return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
  354. }
  355. cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], serialized)
  356. mac := hmac.New(sha256.New, key.hmacKey[:])
  357. mac.Write(encrypted[:len(encrypted)-sha256.Size])
  358. mac.Sum(macBytes[:0])
  359. return encrypted, nil
  360. }
  361. func (c *Conn) decryptTicket(encrypted []byte) (serialized []byte, usedOldKey bool) {
  362. if c.config.SessionTicketsDisabled ||
  363. len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
  364. return nil, false
  365. }
  366. keyName := encrypted[:ticketKeyNameLen]
  367. iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
  368. macBytes := encrypted[len(encrypted)-sha256.Size:]
  369. keys := c.config.ticketKeys()
  370. keyIndex := -1
  371. for i, candidateKey := range keys {
  372. if bytes.Equal(keyName, candidateKey.keyName[:]) {
  373. keyIndex = i
  374. break
  375. }
  376. }
  377. if keyIndex == -1 {
  378. return nil, false
  379. }
  380. key := &keys[keyIndex]
  381. mac := hmac.New(sha256.New, key.hmacKey[:])
  382. mac.Write(encrypted[:len(encrypted)-sha256.Size])
  383. expected := mac.Sum(nil)
  384. if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
  385. return nil, false
  386. }
  387. block, err := aes.NewCipher(key.aesKey[:])
  388. if err != nil {
  389. return nil, false
  390. }
  391. ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
  392. plaintext := ciphertext
  393. cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
  394. return plaintext, keyIndex > 0
  395. }