Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

ticket.go 8.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. )
  15. // A SessionTicketSealer provides a way to securely encapsulate
  16. // session state for storage on the client. All methods are safe for
  17. // concurrent use.
  18. type SessionTicketSealer interface {
  19. // Seal returns a session ticket value that can be later passed to Unseal
  20. // to recover the content, usually by encrypting it. The ticket will be sent
  21. // to the client to be stored, and will be sent back in plaintext, so it can
  22. // be read and modified by an attacker.
  23. Seal(cs *ConnectionState, content []byte) (ticket []byte, err error)
  24. // Unseal returns a session ticket contents. The ticket can't be safely
  25. // assumed to have been generated by Seal.
  26. // If unable to unseal the ticket, the connection will proceed with a
  27. // complete handshake.
  28. Unseal(chi *ClientHelloInfo, ticket []byte) (content []byte, success bool)
  29. }
  30. // sessionState contains the information that is serialized into a session
  31. // ticket in order to later resume a connection.
  32. type sessionState struct {
  33. vers uint16
  34. cipherSuite uint16
  35. masterSecret []byte
  36. certificates [][]byte
  37. // usedOldKey is true if the ticket from which this session came from
  38. // was encrypted with an older key and thus should be refreshed.
  39. usedOldKey bool
  40. }
  41. func (s *sessionState) equal(i interface{}) bool {
  42. s1, ok := i.(*sessionState)
  43. if !ok {
  44. return false
  45. }
  46. if s.vers != s1.vers ||
  47. s.cipherSuite != s1.cipherSuite ||
  48. !bytes.Equal(s.masterSecret, s1.masterSecret) {
  49. return false
  50. }
  51. if len(s.certificates) != len(s1.certificates) {
  52. return false
  53. }
  54. for i := range s.certificates {
  55. if !bytes.Equal(s.certificates[i], s1.certificates[i]) {
  56. return false
  57. }
  58. }
  59. return true
  60. }
  61. func (s *sessionState) marshal() []byte {
  62. length := 2 + 2 + 2 + len(s.masterSecret) + 2
  63. for _, cert := range s.certificates {
  64. length += 4 + len(cert)
  65. }
  66. ret := make([]byte, length)
  67. x := ret
  68. x[0] = byte(s.vers >> 8)
  69. x[1] = byte(s.vers)
  70. x[2] = byte(s.cipherSuite >> 8)
  71. x[3] = byte(s.cipherSuite)
  72. x[4] = byte(len(s.masterSecret) >> 8)
  73. x[5] = byte(len(s.masterSecret))
  74. x = x[6:]
  75. copy(x, s.masterSecret)
  76. x = x[len(s.masterSecret):]
  77. x[0] = byte(len(s.certificates) >> 8)
  78. x[1] = byte(len(s.certificates))
  79. x = x[2:]
  80. for _, cert := range s.certificates {
  81. x[0] = byte(len(cert) >> 24)
  82. x[1] = byte(len(cert) >> 16)
  83. x[2] = byte(len(cert) >> 8)
  84. x[3] = byte(len(cert))
  85. copy(x[4:], cert)
  86. x = x[4+len(cert):]
  87. }
  88. return ret
  89. }
  90. func (s *sessionState) unmarshal(data []byte) alert {
  91. if len(data) < 8 {
  92. return alertDecodeError
  93. }
  94. s.vers = uint16(data[0])<<8 | uint16(data[1])
  95. s.cipherSuite = uint16(data[2])<<8 | uint16(data[3])
  96. masterSecretLen := int(data[4])<<8 | int(data[5])
  97. data = data[6:]
  98. if len(data) < masterSecretLen {
  99. return alertDecodeError
  100. }
  101. s.masterSecret = data[:masterSecretLen]
  102. data = data[masterSecretLen:]
  103. if len(data) < 2 {
  104. return alertDecodeError
  105. }
  106. numCerts := int(data[0])<<8 | int(data[1])
  107. data = data[2:]
  108. s.certificates = make([][]byte, numCerts)
  109. for i := range s.certificates {
  110. if len(data) < 4 {
  111. return alertDecodeError
  112. }
  113. certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3])
  114. data = data[4:]
  115. if certLen < 0 {
  116. return alertDecodeError
  117. }
  118. if len(data) < certLen {
  119. return alertDecodeError
  120. }
  121. s.certificates[i] = data[:certLen]
  122. data = data[certLen:]
  123. }
  124. if len(data) != 0 {
  125. return alertDecodeError
  126. }
  127. return alertSuccess
  128. }
  129. type sessionState13 struct {
  130. vers uint16
  131. suite uint16
  132. ageAdd uint32
  133. createdAt uint64
  134. maxEarlyDataLen uint32
  135. pskSecret []byte
  136. alpnProtocol string
  137. SNI string
  138. }
  139. func (s *sessionState13) equal(i interface{}) bool {
  140. s1, ok := i.(*sessionState13)
  141. if !ok {
  142. return false
  143. }
  144. return s.vers == s1.vers &&
  145. s.suite == s1.suite &&
  146. s.ageAdd == s1.ageAdd &&
  147. s.createdAt == s1.createdAt &&
  148. s.maxEarlyDataLen == s1.maxEarlyDataLen &&
  149. subtle.ConstantTimeCompare(s.pskSecret, s1.pskSecret) == 1 &&
  150. s.alpnProtocol == s1.alpnProtocol &&
  151. s.SNI == s1.SNI
  152. }
  153. func (s *sessionState13) marshal() []byte {
  154. length := 2 + 2 + 4 + 8 + 4 + 2 + len(s.pskSecret) + 2 + len(s.alpnProtocol) + 2 + len(s.SNI)
  155. x := make([]byte, length)
  156. x[0] = byte(s.vers >> 8)
  157. x[1] = byte(s.vers)
  158. x[2] = byte(s.suite >> 8)
  159. x[3] = byte(s.suite)
  160. x[4] = byte(s.ageAdd >> 24)
  161. x[5] = byte(s.ageAdd >> 16)
  162. x[6] = byte(s.ageAdd >> 8)
  163. x[7] = byte(s.ageAdd)
  164. x[8] = byte(s.createdAt >> 56)
  165. x[9] = byte(s.createdAt >> 48)
  166. x[10] = byte(s.createdAt >> 40)
  167. x[11] = byte(s.createdAt >> 32)
  168. x[12] = byte(s.createdAt >> 24)
  169. x[13] = byte(s.createdAt >> 16)
  170. x[14] = byte(s.createdAt >> 8)
  171. x[15] = byte(s.createdAt)
  172. x[16] = byte(s.maxEarlyDataLen >> 24)
  173. x[17] = byte(s.maxEarlyDataLen >> 16)
  174. x[18] = byte(s.maxEarlyDataLen >> 8)
  175. x[19] = byte(s.maxEarlyDataLen)
  176. x[20] = byte(len(s.pskSecret) >> 8)
  177. x[21] = byte(len(s.pskSecret))
  178. copy(x[22:], s.pskSecret)
  179. z := x[22+len(s.pskSecret):]
  180. z[0] = byte(len(s.alpnProtocol) >> 8)
  181. z[1] = byte(len(s.alpnProtocol))
  182. copy(z[2:], s.alpnProtocol)
  183. z = z[2+len(s.alpnProtocol):]
  184. z[0] = byte(len(s.SNI) >> 8)
  185. z[1] = byte(len(s.SNI))
  186. copy(z[2:], s.SNI)
  187. return x
  188. }
  189. func (s *sessionState13) unmarshal(data []byte) alert {
  190. if len(data) < 24 {
  191. return alertDecodeError
  192. }
  193. s.vers = uint16(data[0])<<8 | uint16(data[1])
  194. s.suite = uint16(data[2])<<8 | uint16(data[3])
  195. s.ageAdd = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
  196. s.createdAt = uint64(data[8])<<56 | uint64(data[9])<<48 | uint64(data[10])<<40 | uint64(data[11])<<32 |
  197. uint64(data[12])<<24 | uint64(data[13])<<16 | uint64(data[14])<<8 | uint64(data[15])
  198. s.maxEarlyDataLen = uint32(data[16])<<24 | uint32(data[17])<<16 | uint32(data[18])<<8 | uint32(data[19])
  199. l := int(data[20])<<8 | int(data[21])
  200. if len(data) < 22+l+2 {
  201. return alertDecodeError
  202. }
  203. s.pskSecret = data[22 : 22+l]
  204. z := data[22+l:]
  205. l = int(z[0])<<8 | int(z[1])
  206. if len(z) < 2+l+2 {
  207. return alertDecodeError
  208. }
  209. s.alpnProtocol = string(z[2 : 2+l])
  210. z = z[2+l:]
  211. l = int(z[0])<<8 | int(z[1])
  212. if len(z) != 2+l {
  213. return alertDecodeError
  214. }
  215. s.SNI = string(z[2 : 2+l])
  216. return alertSuccess
  217. }
  218. func (c *Conn) encryptTicket(serialized []byte) ([]byte, error) {
  219. encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(serialized)+sha256.Size)
  220. keyName := encrypted[:ticketKeyNameLen]
  221. iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
  222. macBytes := encrypted[len(encrypted)-sha256.Size:]
  223. if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
  224. return nil, err
  225. }
  226. key := c.config.ticketKeys()[0]
  227. copy(keyName, key.keyName[:])
  228. block, err := aes.NewCipher(key.aesKey[:])
  229. if err != nil {
  230. return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
  231. }
  232. cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], serialized)
  233. mac := hmac.New(sha256.New, key.hmacKey[:])
  234. mac.Write(encrypted[:len(encrypted)-sha256.Size])
  235. mac.Sum(macBytes[:0])
  236. return encrypted, nil
  237. }
  238. func (c *Conn) decryptTicket(encrypted []byte) (serialized []byte, usedOldKey bool) {
  239. if c.config.SessionTicketsDisabled ||
  240. len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
  241. return nil, false
  242. }
  243. keyName := encrypted[:ticketKeyNameLen]
  244. iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
  245. macBytes := encrypted[len(encrypted)-sha256.Size:]
  246. keys := c.config.ticketKeys()
  247. keyIndex := -1
  248. for i, candidateKey := range keys {
  249. if bytes.Equal(keyName, candidateKey.keyName[:]) {
  250. keyIndex = i
  251. break
  252. }
  253. }
  254. if keyIndex == -1 {
  255. return nil, false
  256. }
  257. key := &keys[keyIndex]
  258. mac := hmac.New(sha256.New, key.hmacKey[:])
  259. mac.Write(encrypted[:len(encrypted)-sha256.Size])
  260. expected := mac.Sum(nil)
  261. if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
  262. return nil, false
  263. }
  264. block, err := aes.NewCipher(key.aesKey[:])
  265. if err != nil {
  266. return nil, false
  267. }
  268. ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
  269. plaintext := ciphertext
  270. cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
  271. return plaintext, keyIndex > 0
  272. }