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.

183 lignes
4.1 KiB

  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. // sessionState contains the information that is serialized into a session
  16. // ticket in order to later resume a connection.
  17. type sessionState struct {
  18. vers uint16
  19. cipherSuite uint16
  20. masterSecret []byte
  21. certificates [][]byte
  22. }
  23. func (s *sessionState) equal(i interface{}) bool {
  24. s1, ok := i.(*sessionState)
  25. if !ok {
  26. return false
  27. }
  28. if s.vers != s1.vers ||
  29. s.cipherSuite != s1.cipherSuite ||
  30. !bytes.Equal(s.masterSecret, s1.masterSecret) {
  31. return false
  32. }
  33. if len(s.certificates) != len(s1.certificates) {
  34. return false
  35. }
  36. for i := range s.certificates {
  37. if !bytes.Equal(s.certificates[i], s1.certificates[i]) {
  38. return false
  39. }
  40. }
  41. return true
  42. }
  43. func (s *sessionState) marshal() []byte {
  44. length := 2 + 2 + 2 + len(s.masterSecret) + 2
  45. for _, cert := range s.certificates {
  46. length += 4 + len(cert)
  47. }
  48. ret := make([]byte, length)
  49. x := ret
  50. x[0] = byte(s.vers >> 8)
  51. x[1] = byte(s.vers)
  52. x[2] = byte(s.cipherSuite >> 8)
  53. x[3] = byte(s.cipherSuite)
  54. x[4] = byte(len(s.masterSecret) >> 8)
  55. x[5] = byte(len(s.masterSecret))
  56. x = x[6:]
  57. copy(x, s.masterSecret)
  58. x = x[len(s.masterSecret):]
  59. x[0] = byte(len(s.certificates) >> 8)
  60. x[1] = byte(len(s.certificates))
  61. x = x[2:]
  62. for _, cert := range s.certificates {
  63. x[0] = byte(len(cert) >> 24)
  64. x[1] = byte(len(cert) >> 16)
  65. x[2] = byte(len(cert) >> 8)
  66. x[3] = byte(len(cert))
  67. copy(x[4:], cert)
  68. x = x[4+len(cert):]
  69. }
  70. return ret
  71. }
  72. func (s *sessionState) unmarshal(data []byte) bool {
  73. if len(data) < 8 {
  74. return false
  75. }
  76. s.vers = uint16(data[0])<<8 | uint16(data[1])
  77. s.cipherSuite = uint16(data[2])<<8 | uint16(data[3])
  78. masterSecretLen := int(data[4])<<8 | int(data[5])
  79. data = data[6:]
  80. if len(data) < masterSecretLen {
  81. return false
  82. }
  83. s.masterSecret = data[:masterSecretLen]
  84. data = data[masterSecretLen:]
  85. if len(data) < 2 {
  86. return false
  87. }
  88. numCerts := int(data[0])<<8 | int(data[1])
  89. data = data[2:]
  90. s.certificates = make([][]byte, numCerts)
  91. for i := range s.certificates {
  92. if len(data) < 4 {
  93. return false
  94. }
  95. certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3])
  96. data = data[4:]
  97. if certLen < 0 {
  98. return false
  99. }
  100. if len(data) < certLen {
  101. return false
  102. }
  103. s.certificates[i] = data[:certLen]
  104. data = data[certLen:]
  105. }
  106. if len(data) > 0 {
  107. return false
  108. }
  109. return true
  110. }
  111. func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
  112. serialized := state.marshal()
  113. encrypted := make([]byte, aes.BlockSize+len(serialized)+sha256.Size)
  114. iv := encrypted[:aes.BlockSize]
  115. macBytes := encrypted[len(encrypted)-sha256.Size:]
  116. if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
  117. return nil, err
  118. }
  119. block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
  120. if err != nil {
  121. return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
  122. }
  123. cipher.NewCTR(block, iv).XORKeyStream(encrypted[aes.BlockSize:], serialized)
  124. mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
  125. mac.Write(encrypted[:len(encrypted)-sha256.Size])
  126. mac.Sum(macBytes[:0])
  127. return encrypted, nil
  128. }
  129. func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
  130. if len(encrypted) < aes.BlockSize+sha256.Size {
  131. return nil, false
  132. }
  133. iv := encrypted[:aes.BlockSize]
  134. macBytes := encrypted[len(encrypted)-sha256.Size:]
  135. mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32])
  136. mac.Write(encrypted[:len(encrypted)-sha256.Size])
  137. expected := mac.Sum(nil)
  138. if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
  139. return nil, false
  140. }
  141. block, err := aes.NewCipher(c.config.SessionTicketKey[:16])
  142. if err != nil {
  143. return nil, false
  144. }
  145. ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
  146. plaintext := ciphertext
  147. cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
  148. state := new(sessionState)
  149. ok := state.unmarshal(plaintext)
  150. return state, ok
  151. }