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.

handshake_server.go 8.0 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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/subtle"
  17. "crypto/x509"
  18. "io"
  19. "os"
  20. )
  21. type cipherSuite struct {
  22. id uint16 // The number of this suite on the wire.
  23. hashLength, cipherKeyLength int
  24. // TODO(agl): need a method to create the cipher and hash interfaces.
  25. }
  26. var cipherSuites = []cipherSuite{
  27. cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 20, 16},
  28. }
  29. func (c *Conn) serverHandshake() os.Error {
  30. config := c.config
  31. msg, err := c.readHandshake()
  32. if err != nil {
  33. return err
  34. }
  35. clientHello, ok := msg.(*clientHelloMsg)
  36. if !ok {
  37. return c.sendAlert(alertUnexpectedMessage)
  38. }
  39. vers, ok := mutualVersion(clientHello.vers)
  40. if !ok {
  41. return c.sendAlert(alertProtocolVersion)
  42. }
  43. c.vers = vers
  44. c.haveVers = true
  45. finishedHash := newFinishedHash()
  46. finishedHash.Write(clientHello.marshal())
  47. hello := new(serverHelloMsg)
  48. // We only support a single ciphersuite so we look for it in the list
  49. // of client supported suites.
  50. //
  51. // TODO(agl): Add additional cipher suites.
  52. var suite *cipherSuite
  53. for _, id := range clientHello.cipherSuites {
  54. for _, supported := range cipherSuites {
  55. if supported.id == id {
  56. suite = &supported
  57. break
  58. }
  59. }
  60. }
  61. foundCompression := false
  62. // We only support null compression, so check that the client offered it.
  63. for _, compression := range clientHello.compressionMethods {
  64. if compression == compressionNone {
  65. foundCompression = true
  66. break
  67. }
  68. }
  69. if suite == nil || !foundCompression {
  70. return c.sendAlert(alertHandshakeFailure)
  71. }
  72. hello.vers = vers
  73. hello.cipherSuite = suite.id
  74. t := uint32(config.Time())
  75. hello.random = make([]byte, 32)
  76. hello.random[0] = byte(t >> 24)
  77. hello.random[1] = byte(t >> 16)
  78. hello.random[2] = byte(t >> 8)
  79. hello.random[3] = byte(t)
  80. _, err = io.ReadFull(config.Rand, hello.random[4:])
  81. if err != nil {
  82. return c.sendAlert(alertInternalError)
  83. }
  84. hello.compressionMethod = compressionNone
  85. if clientHello.nextProtoNeg {
  86. hello.nextProtoNeg = true
  87. hello.nextProtos = config.NextProtos
  88. }
  89. finishedHash.Write(hello.marshal())
  90. c.writeRecord(recordTypeHandshake, hello.marshal())
  91. if len(config.Certificates) == 0 {
  92. return c.sendAlert(alertInternalError)
  93. }
  94. certMsg := new(certificateMsg)
  95. certMsg.certificates = config.Certificates[0].Certificate
  96. finishedHash.Write(certMsg.marshal())
  97. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  98. if config.AuthenticateClient {
  99. // Request a client certificate
  100. certReq := new(certificateRequestMsg)
  101. certReq.certificateTypes = []byte{certTypeRSASign}
  102. // An empty list of certificateAuthorities signals to
  103. // the client that it may send any certificate in response
  104. // to our request.
  105. finishedHash.Write(certReq.marshal())
  106. c.writeRecord(recordTypeHandshake, certReq.marshal())
  107. }
  108. helloDone := new(serverHelloDoneMsg)
  109. finishedHash.Write(helloDone.marshal())
  110. c.writeRecord(recordTypeHandshake, helloDone.marshal())
  111. var pub *rsa.PublicKey
  112. if config.AuthenticateClient {
  113. // Get client certificate
  114. msg, err = c.readHandshake()
  115. if err != nil {
  116. return err
  117. }
  118. certMsg, ok = msg.(*certificateMsg)
  119. if !ok {
  120. return c.sendAlert(alertUnexpectedMessage)
  121. }
  122. finishedHash.Write(certMsg.marshal())
  123. certs := make([]*x509.Certificate, len(certMsg.certificates))
  124. for i, asn1Data := range certMsg.certificates {
  125. cert, err := x509.ParseCertificate(asn1Data)
  126. if err != nil {
  127. c.sendAlert(alertBadCertificate)
  128. return os.ErrorString("could not parse client's certificate: " + err.String())
  129. }
  130. certs[i] = cert
  131. }
  132. // TODO(agl): do better validation of certs: max path length, name restrictions etc.
  133. for i := 1; i < len(certs); i++ {
  134. if err := certs[i-1].CheckSignatureFrom(certs[i]); err != nil {
  135. c.sendAlert(alertBadCertificate)
  136. return os.ErrorString("could not validate certificate signature: " + err.String())
  137. }
  138. }
  139. if len(certs) > 0 {
  140. key, ok := certs[0].PublicKey.(*rsa.PublicKey)
  141. if !ok {
  142. return c.sendAlert(alertUnsupportedCertificate)
  143. }
  144. pub = key
  145. c.peerCertificates = certs
  146. }
  147. }
  148. // Get client key exchange
  149. msg, err = c.readHandshake()
  150. if err != nil {
  151. return err
  152. }
  153. ckx, ok := msg.(*clientKeyExchangeMsg)
  154. if !ok {
  155. return c.sendAlert(alertUnexpectedMessage)
  156. }
  157. finishedHash.Write(ckx.marshal())
  158. // If we received a client cert in response to our certificate request message,
  159. // the client will send us a certificateVerifyMsg immediately after the
  160. // clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preceeding
  161. // handshake-layer messages that is signed using the private key corresponding
  162. // to the client's certificate. This allows us to verify that the client is in
  163. // posession of the private key of the certificate.
  164. if len(c.peerCertificates) > 0 {
  165. msg, err = c.readHandshake()
  166. if err != nil {
  167. return err
  168. }
  169. certVerify, ok := msg.(*certificateVerifyMsg)
  170. if !ok {
  171. return c.sendAlert(alertUnexpectedMessage)
  172. }
  173. digest := make([]byte, 36)
  174. copy(digest[0:16], finishedHash.serverMD5.Sum())
  175. copy(digest[16:36], finishedHash.serverSHA1.Sum())
  176. err = rsa.VerifyPKCS1v15(pub, rsa.HashMD5SHA1, digest, certVerify.signature)
  177. if err != nil {
  178. c.sendAlert(alertBadCertificate)
  179. return os.ErrorString("could not validate signature of connection nonces: " + err.String())
  180. }
  181. finishedHash.Write(certVerify.marshal())
  182. }
  183. preMasterSecret := make([]byte, 48)
  184. _, err = io.ReadFull(config.Rand, preMasterSecret[2:])
  185. if err != nil {
  186. return c.sendAlert(alertInternalError)
  187. }
  188. err = rsa.DecryptPKCS1v15SessionKey(config.Rand, config.Certificates[0].PrivateKey, ckx.ciphertext, preMasterSecret)
  189. if err != nil {
  190. return c.sendAlert(alertHandshakeFailure)
  191. }
  192. // We don't check the version number in the premaster secret. For one,
  193. // by checking it, we would leak information about the validity of the
  194. // encrypted pre-master secret. Secondly, it provides only a small
  195. // benefit against a downgrade attack and some implementations send the
  196. // wrong version anyway. See the discussion at the end of section
  197. // 7.4.7.1 of RFC 4346.
  198. masterSecret, clientMAC, serverMAC, clientKey, serverKey :=
  199. keysFromPreMasterSecret11(preMasterSecret, clientHello.random, hello.random, suite.hashLength, suite.cipherKeyLength)
  200. cipher, _ := rc4.NewCipher(clientKey)
  201. c.in.prepareCipherSpec(cipher, hmac.NewSHA1(clientMAC))
  202. c.readRecord(recordTypeChangeCipherSpec)
  203. if err := c.error(); err != nil {
  204. return err
  205. }
  206. if hello.nextProtoNeg {
  207. msg, err = c.readHandshake()
  208. if err != nil {
  209. return err
  210. }
  211. nextProto, ok := msg.(*nextProtoMsg)
  212. if !ok {
  213. return c.sendAlert(alertUnexpectedMessage)
  214. }
  215. finishedHash.Write(nextProto.marshal())
  216. c.clientProtocol = nextProto.proto
  217. }
  218. msg, err = c.readHandshake()
  219. if err != nil {
  220. return err
  221. }
  222. clientFinished, ok := msg.(*finishedMsg)
  223. if !ok {
  224. return c.sendAlert(alertUnexpectedMessage)
  225. }
  226. verify := finishedHash.clientSum(masterSecret)
  227. if len(verify) != len(clientFinished.verifyData) ||
  228. subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
  229. return c.sendAlert(alertHandshakeFailure)
  230. }
  231. finishedHash.Write(clientFinished.marshal())
  232. cipher2, _ := rc4.NewCipher(serverKey)
  233. c.out.prepareCipherSpec(cipher2, hmac.NewSHA1(serverMAC))
  234. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  235. finished := new(finishedMsg)
  236. finished.verifyData = finishedHash.serverSum(masterSecret)
  237. c.writeRecord(recordTypeHandshake, finished.marshal())
  238. c.handshakeComplete = true
  239. c.cipherSuite = TLS_RSA_WITH_RC4_128_SHA
  240. return nil
  241. }