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.

349 lignes
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. }