Alternative TLS implementation in Go
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

183 rindas
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. }