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

301 line
8.6 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/rsa"
  7. "crypto/subtle"
  8. "crypto/x509"
  9. "io"
  10. "os"
  11. )
  12. func (c *Conn) clientHandshake() os.Error {
  13. finishedHash := newFinishedHash()
  14. if c.config == nil {
  15. c.config = defaultConfig()
  16. }
  17. hello := &clientHelloMsg{
  18. vers: maxVersion,
  19. cipherSuites: c.config.cipherSuites(),
  20. compressionMethods: []uint8{compressionNone},
  21. random: make([]byte, 32),
  22. ocspStapling: true,
  23. serverName: c.config.ServerName,
  24. supportedCurves: []uint16{curveP256, curveP384, curveP521},
  25. supportedPoints: []uint8{pointFormatUncompressed},
  26. }
  27. t := uint32(c.config.time())
  28. hello.random[0] = byte(t >> 24)
  29. hello.random[1] = byte(t >> 16)
  30. hello.random[2] = byte(t >> 8)
  31. hello.random[3] = byte(t)
  32. _, err := io.ReadFull(c.config.rand(), hello.random[4:])
  33. if err != nil {
  34. c.sendAlert(alertInternalError)
  35. return os.ErrorString("short read from Rand")
  36. }
  37. finishedHash.Write(hello.marshal())
  38. c.writeRecord(recordTypeHandshake, hello.marshal())
  39. msg, err := c.readHandshake()
  40. if err != nil {
  41. return err
  42. }
  43. serverHello, ok := msg.(*serverHelloMsg)
  44. if !ok {
  45. return c.sendAlert(alertUnexpectedMessage)
  46. }
  47. finishedHash.Write(serverHello.marshal())
  48. vers, ok := mutualVersion(serverHello.vers)
  49. if !ok {
  50. c.sendAlert(alertProtocolVersion)
  51. }
  52. c.vers = vers
  53. c.haveVers = true
  54. if serverHello.compressionMethod != compressionNone {
  55. return c.sendAlert(alertUnexpectedMessage)
  56. }
  57. suite, suiteId := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
  58. if suite == nil {
  59. return c.sendAlert(alertHandshakeFailure)
  60. }
  61. msg, err = c.readHandshake()
  62. if err != nil {
  63. return err
  64. }
  65. certMsg, ok := msg.(*certificateMsg)
  66. if !ok || len(certMsg.certificates) == 0 {
  67. return c.sendAlert(alertUnexpectedMessage)
  68. }
  69. finishedHash.Write(certMsg.marshal())
  70. certs := make([]*x509.Certificate, len(certMsg.certificates))
  71. chain := NewCASet()
  72. for i, asn1Data := range certMsg.certificates {
  73. cert, err := x509.ParseCertificate(asn1Data)
  74. if err != nil {
  75. c.sendAlert(alertBadCertificate)
  76. return os.ErrorString("failed to parse certificate from server: " + err.String())
  77. }
  78. certs[i] = cert
  79. chain.AddCert(cert)
  80. }
  81. // If we don't have a root CA set configured then anything is accepted.
  82. // TODO(rsc): Find certificates for OS X 10.6.
  83. for cur := certs[0]; c.config.RootCAs != nil; {
  84. parent := c.config.RootCAs.FindVerifiedParent(cur)
  85. if parent != nil {
  86. break
  87. }
  88. parent = chain.FindVerifiedParent(cur)
  89. if parent == nil {
  90. c.sendAlert(alertBadCertificate)
  91. return os.ErrorString("could not find root certificate for chain")
  92. }
  93. if !parent.BasicConstraintsValid || !parent.IsCA {
  94. c.sendAlert(alertBadCertificate)
  95. return os.ErrorString("intermediate certificate does not have CA bit set")
  96. }
  97. // KeyUsage status flags are ignored. From Engineering
  98. // Security, Peter Gutmann: A European government CA marked its
  99. // signing certificates as being valid for encryption only, but
  100. // no-one noticed. Another European CA marked its signature
  101. // keys as not being valid for signatures. A different CA
  102. // marked its own trusted root certificate as being invalid for
  103. // certificate signing. Another national CA distributed a
  104. // certificate to be used to encrypt data for the country’s tax
  105. // authority that was marked as only being usable for digital
  106. // signatures but not for encryption. Yet another CA reversed
  107. // the order of the bit flags in the keyUsage due to confusion
  108. // over encoding endianness, essentially setting a random
  109. // keyUsage in certificates that it issued. Another CA created
  110. // a self-invalidating certificate by adding a certificate
  111. // policy statement stipulating that the certificate had to be
  112. // used strictly as specified in the keyUsage, and a keyUsage
  113. // containing a flag indicating that the RSA encryption key
  114. // could only be used for Diffie-Hellman key agreement.
  115. cur = parent
  116. }
  117. if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok {
  118. return c.sendAlert(alertUnsupportedCertificate)
  119. }
  120. c.peerCertificates = certs
  121. if serverHello.certStatus {
  122. msg, err = c.readHandshake()
  123. if err != nil {
  124. return err
  125. }
  126. cs, ok := msg.(*certificateStatusMsg)
  127. if !ok {
  128. return c.sendAlert(alertUnexpectedMessage)
  129. }
  130. finishedHash.Write(cs.marshal())
  131. if cs.statusType == statusTypeOCSP {
  132. c.ocspResponse = cs.response
  133. }
  134. }
  135. msg, err = c.readHandshake()
  136. if err != nil {
  137. return err
  138. }
  139. keyAgreement := suite.ka()
  140. skx, ok := msg.(*serverKeyExchangeMsg)
  141. if ok {
  142. finishedHash.Write(skx.marshal())
  143. err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx)
  144. if err != nil {
  145. c.sendAlert(alertUnexpectedMessage)
  146. return err
  147. }
  148. msg, err = c.readHandshake()
  149. if err != nil {
  150. return err
  151. }
  152. }
  153. transmitCert := false
  154. certReq, ok := msg.(*certificateRequestMsg)
  155. if ok {
  156. // We only accept certificates with RSA keys.
  157. rsaAvail := false
  158. for _, certType := range certReq.certificateTypes {
  159. if certType == certTypeRSASign {
  160. rsaAvail = true
  161. break
  162. }
  163. }
  164. // For now, only send a certificate back if the server gives us an
  165. // empty list of certificateAuthorities.
  166. //
  167. // RFC 4346 on the certificateAuthorities field:
  168. // A list of the distinguished names of acceptable certificate
  169. // authorities. These distinguished names may specify a desired
  170. // distinguished name for a root CA or for a subordinate CA; thus,
  171. // this message can be used to describe both known roots and a
  172. // desired authorization space. If the certificate_authorities
  173. // list is empty then the client MAY send any certificate of the
  174. // appropriate ClientCertificateType, unless there is some
  175. // external arrangement to the contrary.
  176. if rsaAvail && len(certReq.certificateAuthorities) == 0 {
  177. transmitCert = true
  178. }
  179. finishedHash.Write(certReq.marshal())
  180. msg, err = c.readHandshake()
  181. if err != nil {
  182. return err
  183. }
  184. }
  185. shd, ok := msg.(*serverHelloDoneMsg)
  186. if !ok {
  187. return c.sendAlert(alertUnexpectedMessage)
  188. }
  189. finishedHash.Write(shd.marshal())
  190. var cert *x509.Certificate
  191. if transmitCert {
  192. certMsg = new(certificateMsg)
  193. if len(c.config.Certificates) > 0 {
  194. cert, err = x509.ParseCertificate(c.config.Certificates[0].Certificate[0])
  195. if err == nil && cert.PublicKeyAlgorithm == x509.RSA {
  196. certMsg.certificates = c.config.Certificates[0].Certificate
  197. } else {
  198. cert = nil
  199. }
  200. }
  201. finishedHash.Write(certMsg.marshal())
  202. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  203. }
  204. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0])
  205. if err != nil {
  206. c.sendAlert(alertInternalError)
  207. return err
  208. }
  209. if ckx != nil {
  210. finishedHash.Write(ckx.marshal())
  211. c.writeRecord(recordTypeHandshake, ckx.marshal())
  212. }
  213. if cert != nil {
  214. certVerify := new(certificateVerifyMsg)
  215. var digest [36]byte
  216. copy(digest[0:16], finishedHash.serverMD5.Sum())
  217. copy(digest[16:36], finishedHash.serverSHA1.Sum())
  218. signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, rsa.HashMD5SHA1, digest[0:])
  219. if err != nil {
  220. return c.sendAlert(alertInternalError)
  221. }
  222. certVerify.signature = signed
  223. finishedHash.Write(certVerify.marshal())
  224. c.writeRecord(recordTypeHandshake, certVerify.marshal())
  225. }
  226. masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  227. keysFromPreMasterSecret10(preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
  228. clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */ )
  229. clientHash := suite.mac(clientMAC)
  230. c.out.prepareCipherSpec(clientCipher, clientHash)
  231. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  232. finished := new(finishedMsg)
  233. finished.verifyData = finishedHash.clientSum(masterSecret)
  234. finishedHash.Write(finished.marshal())
  235. c.writeRecord(recordTypeHandshake, finished.marshal())
  236. serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */ )
  237. serverHash := suite.mac(serverMAC)
  238. c.in.prepareCipherSpec(serverCipher, serverHash)
  239. c.readRecord(recordTypeChangeCipherSpec)
  240. if c.err != nil {
  241. return c.err
  242. }
  243. msg, err = c.readHandshake()
  244. if err != nil {
  245. return err
  246. }
  247. serverFinished, ok := msg.(*finishedMsg)
  248. if !ok {
  249. return c.sendAlert(alertUnexpectedMessage)
  250. }
  251. verify := finishedHash.serverSum(masterSecret)
  252. if len(verify) != len(serverFinished.verifyData) ||
  253. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  254. return c.sendAlert(alertHandshakeFailure)
  255. }
  256. c.handshakeComplete = true
  257. c.cipherSuite = suiteId
  258. return nil
  259. }