Alternative TLS implementation in Go
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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