You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

299 line
7.9 KiB

  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. import (
  6. "crypto"
  7. "crypto/rsa"
  8. "crypto/subtle"
  9. "crypto/x509"
  10. "io"
  11. "os"
  12. )
  13. func (c *Conn) serverHandshake() os.Error {
  14. config := c.config
  15. msg, err := c.readHandshake()
  16. if err != nil {
  17. return err
  18. }
  19. clientHello, ok := msg.(*clientHelloMsg)
  20. if !ok {
  21. return c.sendAlert(alertUnexpectedMessage)
  22. }
  23. vers, ok := mutualVersion(clientHello.vers)
  24. if !ok {
  25. return c.sendAlert(alertProtocolVersion)
  26. }
  27. c.vers = vers
  28. c.haveVers = true
  29. finishedHash := newFinishedHash()
  30. finishedHash.Write(clientHello.marshal())
  31. hello := new(serverHelloMsg)
  32. supportedCurve := false
  33. Curves:
  34. for _, curve := range clientHello.supportedCurves {
  35. switch curve {
  36. case curveP256, curveP384, curveP521:
  37. supportedCurve = true
  38. break Curves
  39. }
  40. }
  41. supportedPointFormat := false
  42. for _, pointFormat := range clientHello.supportedPoints {
  43. if pointFormat == pointFormatUncompressed {
  44. supportedPointFormat = true
  45. break
  46. }
  47. }
  48. ellipticOk := supportedCurve && supportedPointFormat
  49. var suite *cipherSuite
  50. var suiteId uint16
  51. FindCipherSuite:
  52. for _, id := range clientHello.cipherSuites {
  53. for _, supported := range config.cipherSuites() {
  54. if id == supported {
  55. suite = cipherSuites[id]
  56. // Don't select a ciphersuite which we can't
  57. // support for this client.
  58. if suite.elliptic && !ellipticOk {
  59. continue
  60. }
  61. suiteId = id
  62. break FindCipherSuite
  63. }
  64. }
  65. }
  66. foundCompression := false
  67. // We only support null compression, so check that the client offered it.
  68. for _, compression := range clientHello.compressionMethods {
  69. if compression == compressionNone {
  70. foundCompression = true
  71. break
  72. }
  73. }
  74. if suite == nil || !foundCompression {
  75. return c.sendAlert(alertHandshakeFailure)
  76. }
  77. hello.vers = vers
  78. hello.cipherSuite = suiteId
  79. t := uint32(config.time())
  80. hello.random = make([]byte, 32)
  81. hello.random[0] = byte(t >> 24)
  82. hello.random[1] = byte(t >> 16)
  83. hello.random[2] = byte(t >> 8)
  84. hello.random[3] = byte(t)
  85. _, err = io.ReadFull(config.rand(), hello.random[4:])
  86. if err != nil {
  87. return c.sendAlert(alertInternalError)
  88. }
  89. hello.compressionMethod = compressionNone
  90. if clientHello.nextProtoNeg {
  91. hello.nextProtoNeg = true
  92. hello.nextProtos = config.NextProtos
  93. }
  94. if clientHello.ocspStapling && len(config.Certificates[0].OCSPStaple) > 0 {
  95. hello.ocspStapling = true
  96. }
  97. finishedHash.Write(hello.marshal())
  98. c.writeRecord(recordTypeHandshake, hello.marshal())
  99. if len(config.Certificates) == 0 {
  100. return c.sendAlert(alertInternalError)
  101. }
  102. certMsg := new(certificateMsg)
  103. certMsg.certificates = config.Certificates[0].Certificate
  104. finishedHash.Write(certMsg.marshal())
  105. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  106. if hello.ocspStapling {
  107. certStatus := new(certificateStatusMsg)
  108. certStatus.statusType = statusTypeOCSP
  109. certStatus.response = config.Certificates[0].OCSPStaple
  110. finishedHash.Write(certStatus.marshal())
  111. c.writeRecord(recordTypeHandshake, certStatus.marshal())
  112. }
  113. keyAgreement := suite.ka()
  114. skx, err := keyAgreement.generateServerKeyExchange(config, clientHello, hello)
  115. if err != nil {
  116. c.sendAlert(alertHandshakeFailure)
  117. return err
  118. }
  119. if skx != nil {
  120. finishedHash.Write(skx.marshal())
  121. c.writeRecord(recordTypeHandshake, skx.marshal())
  122. }
  123. if config.AuthenticateClient {
  124. // Request a client certificate
  125. certReq := new(certificateRequestMsg)
  126. certReq.certificateTypes = []byte{certTypeRSASign}
  127. // An empty list of certificateAuthorities signals to
  128. // the client that it may send any certificate in response
  129. // to our request.
  130. finishedHash.Write(certReq.marshal())
  131. c.writeRecord(recordTypeHandshake, certReq.marshal())
  132. }
  133. helloDone := new(serverHelloDoneMsg)
  134. finishedHash.Write(helloDone.marshal())
  135. c.writeRecord(recordTypeHandshake, helloDone.marshal())
  136. var pub *rsa.PublicKey
  137. if config.AuthenticateClient {
  138. // Get client certificate
  139. msg, err = c.readHandshake()
  140. if err != nil {
  141. return err
  142. }
  143. certMsg, ok = msg.(*certificateMsg)
  144. if !ok {
  145. return c.sendAlert(alertUnexpectedMessage)
  146. }
  147. finishedHash.Write(certMsg.marshal())
  148. certs := make([]*x509.Certificate, len(certMsg.certificates))
  149. for i, asn1Data := range certMsg.certificates {
  150. cert, err := x509.ParseCertificate(asn1Data)
  151. if err != nil {
  152. c.sendAlert(alertBadCertificate)
  153. return os.NewError("could not parse client's certificate: " + err.String())
  154. }
  155. certs[i] = cert
  156. }
  157. // TODO(agl): do better validation of certs: max path length, name restrictions etc.
  158. for i := 1; i < len(certs); i++ {
  159. if err := certs[i-1].CheckSignatureFrom(certs[i]); err != nil {
  160. c.sendAlert(alertBadCertificate)
  161. return os.NewError("could not validate certificate signature: " + err.String())
  162. }
  163. }
  164. if len(certs) > 0 {
  165. key, ok := certs[0].PublicKey.(*rsa.PublicKey)
  166. if !ok {
  167. return c.sendAlert(alertUnsupportedCertificate)
  168. }
  169. pub = key
  170. c.peerCertificates = certs
  171. }
  172. }
  173. // Get client key exchange
  174. msg, err = c.readHandshake()
  175. if err != nil {
  176. return err
  177. }
  178. ckx, ok := msg.(*clientKeyExchangeMsg)
  179. if !ok {
  180. return c.sendAlert(alertUnexpectedMessage)
  181. }
  182. finishedHash.Write(ckx.marshal())
  183. // If we received a client cert in response to our certificate request message,
  184. // the client will send us a certificateVerifyMsg immediately after the
  185. // clientKeyExchangeMsg. This message is a MD5SHA1 digest of all preceding
  186. // handshake-layer messages that is signed using the private key corresponding
  187. // to the client's certificate. This allows us to verify that the client is in
  188. // possession of the private key of the certificate.
  189. if len(c.peerCertificates) > 0 {
  190. msg, err = c.readHandshake()
  191. if err != nil {
  192. return err
  193. }
  194. certVerify, ok := msg.(*certificateVerifyMsg)
  195. if !ok {
  196. return c.sendAlert(alertUnexpectedMessage)
  197. }
  198. digest := make([]byte, 36)
  199. copy(digest[0:16], finishedHash.serverMD5.Sum())
  200. copy(digest[16:36], finishedHash.serverSHA1.Sum())
  201. err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature)
  202. if err != nil {
  203. c.sendAlert(alertBadCertificate)
  204. return os.NewError("could not validate signature of connection nonces: " + err.String())
  205. }
  206. finishedHash.Write(certVerify.marshal())
  207. }
  208. preMasterSecret, err := keyAgreement.processClientKeyExchange(config, ckx)
  209. if err != nil {
  210. c.sendAlert(alertHandshakeFailure)
  211. return err
  212. }
  213. masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  214. keysFromPreMasterSecret10(preMasterSecret, clientHello.random, hello.random, suite.macLen, suite.keyLen, suite.ivLen)
  215. clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */ )
  216. clientHash := suite.mac(clientMAC)
  217. c.in.prepareCipherSpec(clientCipher, clientHash)
  218. c.readRecord(recordTypeChangeCipherSpec)
  219. if err := c.error(); err != nil {
  220. return err
  221. }
  222. if hello.nextProtoNeg {
  223. msg, err = c.readHandshake()
  224. if err != nil {
  225. return err
  226. }
  227. nextProto, ok := msg.(*nextProtoMsg)
  228. if !ok {
  229. return c.sendAlert(alertUnexpectedMessage)
  230. }
  231. finishedHash.Write(nextProto.marshal())
  232. c.clientProtocol = nextProto.proto
  233. }
  234. msg, err = c.readHandshake()
  235. if err != nil {
  236. return err
  237. }
  238. clientFinished, ok := msg.(*finishedMsg)
  239. if !ok {
  240. return c.sendAlert(alertUnexpectedMessage)
  241. }
  242. verify := finishedHash.clientSum(masterSecret)
  243. if len(verify) != len(clientFinished.verifyData) ||
  244. subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
  245. return c.sendAlert(alertHandshakeFailure)
  246. }
  247. finishedHash.Write(clientFinished.marshal())
  248. serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */ )
  249. serverHash := suite.mac(serverMAC)
  250. c.out.prepareCipherSpec(serverCipher, serverHash)
  251. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  252. finished := new(finishedMsg)
  253. finished.verifyData = finishedHash.serverSum(masterSecret)
  254. c.writeRecord(recordTypeHandshake, finished.marshal())
  255. c.handshakeComplete = true
  256. c.cipherSuite = suiteId
  257. return nil
  258. }