Alternative TLS implementation in Go
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.

handshake_server.go 6.7 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright 2009 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. // The handshake goroutine reads handshake messages from the record processor
  6. // and outputs messages to be written on another channel. It updates the record
  7. // processor with the state of the connection via the control channel. In the
  8. // case of handshake messages that need synchronous processing (because they
  9. // affect the handling of the next record) the record processor knows about
  10. // them and either waits for a control message (Finished) or includes a reply
  11. // channel in the message (ChangeCipherSpec).
  12. import (
  13. "crypto/hmac"
  14. "crypto/rc4"
  15. "crypto/rsa"
  16. "crypto/sha1"
  17. "crypto/subtle"
  18. "io"
  19. )
  20. type cipherSuite struct {
  21. id uint16 // The number of this suite on the wire.
  22. hashLength, cipherKeyLength int
  23. // TODO(agl): need a method to create the cipher and hash interfaces.
  24. }
  25. var cipherSuites = []cipherSuite{
  26. cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 20, 16},
  27. }
  28. // A serverHandshake performs the server side of the TLS 1.1 handshake protocol.
  29. type serverHandshake struct {
  30. writeChan chan<- interface{}
  31. controlChan chan<- interface{}
  32. msgChan <-chan interface{}
  33. config *Config
  34. }
  35. func (h *serverHandshake) loop(writeChan chan<- interface{}, controlChan chan<- interface{}, msgChan <-chan interface{}, config *Config) {
  36. h.writeChan = writeChan
  37. h.controlChan = controlChan
  38. h.msgChan = msgChan
  39. h.config = config
  40. defer close(writeChan)
  41. defer close(controlChan)
  42. clientHello, ok := h.readHandshakeMsg().(*clientHelloMsg)
  43. if !ok {
  44. h.error(alertUnexpectedMessage)
  45. return
  46. }
  47. major, minor, ok := mutualVersion(clientHello.major, clientHello.minor)
  48. if !ok {
  49. h.error(alertProtocolVersion)
  50. return
  51. }
  52. finishedHash := newFinishedHash()
  53. finishedHash.Write(clientHello.marshal())
  54. hello := new(serverHelloMsg)
  55. // We only support a single ciphersuite so we look for it in the list
  56. // of client supported suites.
  57. //
  58. // TODO(agl): Add additional cipher suites.
  59. var suite *cipherSuite
  60. for _, id := range clientHello.cipherSuites {
  61. for _, supported := range cipherSuites {
  62. if supported.id == id {
  63. suite = &supported
  64. break
  65. }
  66. }
  67. }
  68. foundCompression := false
  69. // We only support null compression, so check that the client offered it.
  70. for _, compression := range clientHello.compressionMethods {
  71. if compression == compressionNone {
  72. foundCompression = true
  73. break
  74. }
  75. }
  76. if suite == nil || !foundCompression {
  77. h.error(alertHandshakeFailure)
  78. return
  79. }
  80. hello.major = major
  81. hello.minor = minor
  82. hello.cipherSuite = suite.id
  83. currentTime := uint32(config.Time())
  84. hello.random = make([]byte, 32)
  85. hello.random[0] = byte(currentTime >> 24)
  86. hello.random[1] = byte(currentTime >> 16)
  87. hello.random[2] = byte(currentTime >> 8)
  88. hello.random[3] = byte(currentTime)
  89. _, err := io.ReadFull(config.Rand, hello.random[4:])
  90. if err != nil {
  91. h.error(alertInternalError)
  92. return
  93. }
  94. hello.compressionMethod = compressionNone
  95. if clientHello.nextProtoNeg {
  96. hello.nextProtoNeg = true
  97. hello.nextProtos = config.NextProtos
  98. }
  99. finishedHash.Write(hello.marshal())
  100. writeChan <- writerSetVersion{major, minor}
  101. writeChan <- hello
  102. if len(config.Certificates) == 0 {
  103. h.error(alertInternalError)
  104. return
  105. }
  106. certMsg := new(certificateMsg)
  107. certMsg.certificates = config.Certificates[0].Certificate
  108. finishedHash.Write(certMsg.marshal())
  109. writeChan <- certMsg
  110. helloDone := new(serverHelloDoneMsg)
  111. finishedHash.Write(helloDone.marshal())
  112. writeChan <- helloDone
  113. ckx, ok := h.readHandshakeMsg().(*clientKeyExchangeMsg)
  114. if !ok {
  115. h.error(alertUnexpectedMessage)
  116. return
  117. }
  118. finishedHash.Write(ckx.marshal())
  119. preMasterSecret := make([]byte, 48)
  120. _, err = io.ReadFull(config.Rand, preMasterSecret[2:])
  121. if err != nil {
  122. h.error(alertInternalError)
  123. return
  124. }
  125. err = rsa.DecryptPKCS1v15SessionKey(config.Rand, config.Certificates[0].PrivateKey, ckx.ciphertext, preMasterSecret)
  126. if err != nil {
  127. h.error(alertHandshakeFailure)
  128. return
  129. }
  130. // We don't check the version number in the premaster secret. For one,
  131. // by checking it, we would leak information about the validity of the
  132. // encrypted pre-master secret. Secondly, it provides only a small
  133. // benefit against a downgrade attack and some implementations send the
  134. // wrong version anyway. See the discussion at the end of section
  135. // 7.4.7.1 of RFC 4346.
  136. masterSecret, clientMAC, serverMAC, clientKey, serverKey :=
  137. keysFromPreMasterSecret11(preMasterSecret, clientHello.random, hello.random, suite.hashLength, suite.cipherKeyLength)
  138. _, ok = h.readHandshakeMsg().(changeCipherSpec)
  139. if !ok {
  140. h.error(alertUnexpectedMessage)
  141. return
  142. }
  143. cipher, _ := rc4.NewCipher(clientKey)
  144. controlChan <- &newCipherSpec{cipher, hmac.New(sha1.New(), clientMAC)}
  145. clientProtocol := ""
  146. if hello.nextProtoNeg {
  147. nextProto, ok := h.readHandshakeMsg().(*nextProtoMsg)
  148. if !ok {
  149. h.error(alertUnexpectedMessage)
  150. return
  151. }
  152. finishedHash.Write(nextProto.marshal())
  153. clientProtocol = nextProto.proto
  154. }
  155. clientFinished, ok := h.readHandshakeMsg().(*finishedMsg)
  156. if !ok {
  157. h.error(alertUnexpectedMessage)
  158. return
  159. }
  160. verify := finishedHash.clientSum(masterSecret)
  161. if len(verify) != len(clientFinished.verifyData) ||
  162. subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
  163. h.error(alertHandshakeFailure)
  164. return
  165. }
  166. controlChan <- ConnectionState{true, "TLS_RSA_WITH_RC4_128_SHA", 0, clientProtocol}
  167. finishedHash.Write(clientFinished.marshal())
  168. cipher2, _ := rc4.NewCipher(serverKey)
  169. writeChan <- writerChangeCipherSpec{cipher2, hmac.New(sha1.New(), serverMAC)}
  170. finished := new(finishedMsg)
  171. finished.verifyData = finishedHash.serverSum(masterSecret)
  172. writeChan <- finished
  173. writeChan <- writerEnableApplicationData{}
  174. for {
  175. _, ok := h.readHandshakeMsg().(*clientHelloMsg)
  176. if !ok {
  177. h.error(alertUnexpectedMessage)
  178. return
  179. }
  180. // We reject all renegotication requests.
  181. writeChan <- alert{alertLevelWarning, alertNoRenegotiation}
  182. }
  183. }
  184. func (h *serverHandshake) readHandshakeMsg() interface{} {
  185. v := <-h.msgChan
  186. if closed(h.msgChan) {
  187. // If the channel closed then the processor received an error
  188. // from the peer and we don't want to echo it back to them.
  189. h.msgChan = nil
  190. return 0
  191. }
  192. if _, ok := v.(alert); ok {
  193. // We got an alert from the processor. We forward to the writer
  194. // and shutdown.
  195. h.writeChan <- v
  196. h.msgChan = nil
  197. return 0
  198. }
  199. return v
  200. }
  201. func (h *serverHandshake) error(e alertType) {
  202. if h.msgChan != nil {
  203. // If we didn't get an error from the processor, then we need
  204. // to tell it about the error.
  205. go func() {
  206. for _ = range h.msgChan {
  207. }
  208. }()
  209. h.controlChan <- ConnectionState{false, "", e, ""}
  210. close(h.controlChan)
  211. h.writeChan <- alert{alertLevelError, e}
  212. }
  213. }