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.

349 lines
9.3 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. "bytes"
  7. "crypto"
  8. "crypto/rsa"
  9. "crypto/subtle"
  10. "crypto/x509"
  11. "errors"
  12. "io"
  13. "strconv"
  14. )
  15. func (c *Conn) clientHandshake() error {
  16. finishedHash := newFinishedHash(versionTLS10)
  17. if c.config == nil {
  18. c.config = defaultConfig()
  19. }
  20. hello := &clientHelloMsg{
  21. vers: maxVersion,
  22. cipherSuites: c.config.cipherSuites(),
  23. compressionMethods: []uint8{compressionNone},
  24. random: make([]byte, 32),
  25. ocspStapling: true,
  26. serverName: c.config.ServerName,
  27. supportedCurves: []uint16{curveP256, curveP384, curveP521},
  28. supportedPoints: []uint8{pointFormatUncompressed},
  29. nextProtoNeg: len(c.config.NextProtos) > 0,
  30. }
  31. t := uint32(c.config.time().Unix())
  32. hello.random[0] = byte(t >> 24)
  33. hello.random[1] = byte(t >> 16)
  34. hello.random[2] = byte(t >> 8)
  35. hello.random[3] = byte(t)
  36. _, err := io.ReadFull(c.config.rand(), hello.random[4:])
  37. if err != nil {
  38. c.sendAlert(alertInternalError)
  39. return errors.New("short read from Rand")
  40. }
  41. finishedHash.Write(hello.marshal())
  42. c.writeRecord(recordTypeHandshake, hello.marshal())
  43. msg, err := c.readHandshake()
  44. if err != nil {
  45. return err
  46. }
  47. serverHello, ok := msg.(*serverHelloMsg)
  48. if !ok {
  49. return c.sendAlert(alertUnexpectedMessage)
  50. }
  51. finishedHash.Write(serverHello.marshal())
  52. vers, ok := mutualVersion(serverHello.vers)
  53. if !ok || vers < versionTLS10 {
  54. // TLS 1.0 is the minimum version supported as a client.
  55. return c.sendAlert(alertProtocolVersion)
  56. }
  57. c.vers = vers
  58. c.haveVers = true
  59. if serverHello.compressionMethod != compressionNone {
  60. return c.sendAlert(alertUnexpectedMessage)
  61. }
  62. if !hello.nextProtoNeg && serverHello.nextProtoNeg {
  63. c.sendAlert(alertHandshakeFailure)
  64. return errors.New("server advertised unrequested NPN")
  65. }
  66. suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
  67. if suite == nil {
  68. return c.sendAlert(alertHandshakeFailure)
  69. }
  70. msg, err = c.readHandshake()
  71. if err != nil {
  72. return err
  73. }
  74. certMsg, ok := msg.(*certificateMsg)
  75. if !ok || len(certMsg.certificates) == 0 {
  76. return c.sendAlert(alertUnexpectedMessage)
  77. }
  78. finishedHash.Write(certMsg.marshal())
  79. certs := make([]*x509.Certificate, len(certMsg.certificates))
  80. for i, asn1Data := range certMsg.certificates {
  81. cert, err := x509.ParseCertificate(asn1Data)
  82. if err != nil {
  83. c.sendAlert(alertBadCertificate)
  84. return errors.New("failed to parse certificate from server: " + err.Error())
  85. }
  86. certs[i] = cert
  87. }
  88. if !c.config.InsecureSkipVerify {
  89. opts := x509.VerifyOptions{
  90. Roots: c.config.RootCAs,
  91. CurrentTime: c.config.time(),
  92. DNSName: c.config.ServerName,
  93. Intermediates: x509.NewCertPool(),
  94. }
  95. for i, cert := range certs {
  96. if i == 0 {
  97. continue
  98. }
  99. opts.Intermediates.AddCert(cert)
  100. }
  101. c.verifiedChains, err = certs[0].Verify(opts)
  102. if err != nil {
  103. c.sendAlert(alertBadCertificate)
  104. return err
  105. }
  106. }
  107. if _, ok := certs[0].PublicKey.(*rsa.PublicKey); !ok {
  108. return c.sendAlert(alertUnsupportedCertificate)
  109. }
  110. c.peerCertificates = certs
  111. if serverHello.ocspStapling {
  112. msg, err = c.readHandshake()
  113. if err != nil {
  114. return err
  115. }
  116. cs, ok := msg.(*certificateStatusMsg)
  117. if !ok {
  118. return c.sendAlert(alertUnexpectedMessage)
  119. }
  120. finishedHash.Write(cs.marshal())
  121. if cs.statusType == statusTypeOCSP {
  122. c.ocspResponse = cs.response
  123. }
  124. }
  125. msg, err = c.readHandshake()
  126. if err != nil {
  127. return err
  128. }
  129. keyAgreement := suite.ka()
  130. skx, ok := msg.(*serverKeyExchangeMsg)
  131. if ok {
  132. finishedHash.Write(skx.marshal())
  133. err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx)
  134. if err != nil {
  135. c.sendAlert(alertUnexpectedMessage)
  136. return err
  137. }
  138. msg, err = c.readHandshake()
  139. if err != nil {
  140. return err
  141. }
  142. }
  143. var certToSend *Certificate
  144. var certRequested bool
  145. certReq, ok := msg.(*certificateRequestMsg)
  146. if ok {
  147. certRequested = true
  148. // RFC 4346 on the certificateAuthorities field:
  149. // A list of the distinguished names of acceptable certificate
  150. // authorities. These distinguished names may specify a desired
  151. // distinguished name for a root CA or for a subordinate CA;
  152. // thus, this message can be used to describe both known roots
  153. // and a desired authorization space. If the
  154. // certificate_authorities list is empty then the client MAY
  155. // send any certificate of the appropriate
  156. // ClientCertificateType, unless there is some external
  157. // arrangement to the contrary.
  158. finishedHash.Write(certReq.marshal())
  159. // For now, we only know how to sign challenges with RSA
  160. rsaAvail := false
  161. for _, certType := range certReq.certificateTypes {
  162. if certType == certTypeRSASign {
  163. rsaAvail = true
  164. break
  165. }
  166. }
  167. // We need to search our list of client certs for one
  168. // where SignatureAlgorithm is RSA and the Issuer is in
  169. // certReq.certificateAuthorities
  170. findCert:
  171. for i, cert := range c.config.Certificates {
  172. if !rsaAvail {
  173. continue
  174. }
  175. leaf := cert.Leaf
  176. if leaf == nil {
  177. if leaf, err = x509.ParseCertificate(cert.Certificate[0]); err != nil {
  178. c.sendAlert(alertInternalError)
  179. return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  180. }
  181. }
  182. if leaf.PublicKeyAlgorithm != x509.RSA {
  183. continue
  184. }
  185. if len(certReq.certificateAuthorities) == 0 {
  186. // they gave us an empty list, so just take the
  187. // first RSA cert from c.config.Certificates
  188. certToSend = &cert
  189. break
  190. }
  191. for _, ca := range certReq.certificateAuthorities {
  192. if bytes.Equal(leaf.RawIssuer, ca) {
  193. certToSend = &cert
  194. break findCert
  195. }
  196. }
  197. }
  198. msg, err = c.readHandshake()
  199. if err != nil {
  200. return err
  201. }
  202. }
  203. shd, ok := msg.(*serverHelloDoneMsg)
  204. if !ok {
  205. return c.sendAlert(alertUnexpectedMessage)
  206. }
  207. finishedHash.Write(shd.marshal())
  208. // If the server requested a certificate then we have to send a
  209. // Certificate message, even if it's empty because we don't have a
  210. // certificate to send.
  211. if certRequested {
  212. certMsg = new(certificateMsg)
  213. if certToSend != nil {
  214. certMsg.certificates = certToSend.Certificate
  215. }
  216. finishedHash.Write(certMsg.marshal())
  217. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  218. }
  219. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0])
  220. if err != nil {
  221. c.sendAlert(alertInternalError)
  222. return err
  223. }
  224. if ckx != nil {
  225. finishedHash.Write(ckx.marshal())
  226. c.writeRecord(recordTypeHandshake, ckx.marshal())
  227. }
  228. if certToSend != nil {
  229. certVerify := new(certificateVerifyMsg)
  230. digest := make([]byte, 0, 36)
  231. digest = finishedHash.serverMD5.Sum(digest)
  232. digest = finishedHash.serverSHA1.Sum(digest)
  233. signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, digest)
  234. if err != nil {
  235. return c.sendAlert(alertInternalError)
  236. }
  237. certVerify.signature = signed
  238. finishedHash.Write(certVerify.marshal())
  239. c.writeRecord(recordTypeHandshake, certVerify.marshal())
  240. }
  241. masterSecret := masterFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random)
  242. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  243. keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen)
  244. clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */)
  245. clientHash := suite.mac(c.vers, clientMAC)
  246. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  247. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  248. if serverHello.nextProtoNeg {
  249. nextProto := new(nextProtoMsg)
  250. proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos)
  251. nextProto.proto = proto
  252. c.clientProtocol = proto
  253. c.clientProtocolFallback = fallback
  254. finishedHash.Write(nextProto.marshal())
  255. c.writeRecord(recordTypeHandshake, nextProto.marshal())
  256. }
  257. finished := new(finishedMsg)
  258. finished.verifyData = finishedHash.clientSum(masterSecret)
  259. finishedHash.Write(finished.marshal())
  260. c.writeRecord(recordTypeHandshake, finished.marshal())
  261. serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */)
  262. serverHash := suite.mac(c.vers, serverMAC)
  263. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  264. c.readRecord(recordTypeChangeCipherSpec)
  265. if err := c.error(); err != nil {
  266. return err
  267. }
  268. msg, err = c.readHandshake()
  269. if err != nil {
  270. return err
  271. }
  272. serverFinished, ok := msg.(*finishedMsg)
  273. if !ok {
  274. return c.sendAlert(alertUnexpectedMessage)
  275. }
  276. verify := finishedHash.serverSum(masterSecret)
  277. if len(verify) != len(serverFinished.verifyData) ||
  278. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  279. return c.sendAlert(alertHandshakeFailure)
  280. }
  281. c.handshakeComplete = true
  282. c.cipherSuite = suite.id
  283. return nil
  284. }
  285. // mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
  286. // set of client and server supported protocols. The set of client supported
  287. // protocols must not be empty. It returns the resulting protocol and flag
  288. // indicating if the fallback case was reached.
  289. func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
  290. for _, s := range serverProtos {
  291. for _, c := range clientProtos {
  292. if s == c {
  293. return s, false
  294. }
  295. }
  296. }
  297. return clientProtos[0], true
  298. }