Alternative TLS implementation in Go
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

718 linhas
20 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/ecdsa"
  8. "crypto/rsa"
  9. "crypto/subtle"
  10. "crypto/x509"
  11. "encoding/asn1"
  12. "errors"
  13. "fmt"
  14. "io"
  15. )
  16. // serverHandshakeState contains details of a server handshake in progress.
  17. // It's discarded once the handshake has completed.
  18. type serverHandshakeState struct {
  19. c *Conn
  20. clientHello *clientHelloMsg
  21. hello *serverHelloMsg
  22. suite *cipherSuite
  23. ellipticOk bool
  24. ecdsaOk bool
  25. rsaDecryptOk bool
  26. rsaSignOk bool
  27. sessionState *sessionState
  28. finishedHash finishedHash
  29. masterSecret []byte
  30. certsFromClient [][]byte
  31. cert *Certificate
  32. }
  33. // serverHandshake performs a TLS handshake as a server.
  34. func (c *Conn) serverHandshake() error {
  35. config := c.config
  36. // If this is the first server handshake, we generate a random key to
  37. // encrypt the tickets with.
  38. config.serverInitOnce.Do(config.serverInit)
  39. hs := serverHandshakeState{
  40. c: c,
  41. }
  42. isResume, err := hs.readClientHello()
  43. if err != nil {
  44. return err
  45. }
  46. hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite.tls12Hash)
  47. hs.finishedHash.Write(hs.clientHello.marshal())
  48. // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
  49. if isResume {
  50. // The client has included a session ticket and so we do an abbreviated handshake.
  51. if err := hs.doResumeHandshake(); err != nil {
  52. return err
  53. }
  54. if err := hs.establishKeys(); err != nil {
  55. return err
  56. }
  57. // ticketSupported is set in a resumption handshake if the
  58. // ticket from the client was encrypted with an old session
  59. // ticket key and thus a refreshed ticket should be sent.
  60. if hs.hello.ticketSupported {
  61. if err := hs.sendSessionTicket(); err != nil {
  62. return err
  63. }
  64. }
  65. if err := hs.sendFinished(c.firstFinished[:]); err != nil {
  66. return err
  67. }
  68. if err := hs.readFinished(nil); err != nil {
  69. return err
  70. }
  71. c.didResume = true
  72. } else {
  73. // The client didn't include a session ticket, or it wasn't
  74. // valid so we do a full handshake.
  75. if err := hs.doFullHandshake(); err != nil {
  76. return err
  77. }
  78. if err := hs.establishKeys(); err != nil {
  79. return err
  80. }
  81. if err := hs.readFinished(c.firstFinished[:]); err != nil {
  82. return err
  83. }
  84. if err := hs.sendSessionTicket(); err != nil {
  85. return err
  86. }
  87. if err := hs.sendFinished(nil); err != nil {
  88. return err
  89. }
  90. }
  91. c.handshakeComplete = true
  92. return nil
  93. }
  94. // readClientHello reads a ClientHello message from the client and decides
  95. // whether we will perform session resumption.
  96. func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
  97. config := hs.c.config
  98. c := hs.c
  99. msg, err := c.readHandshake()
  100. if err != nil {
  101. return false, err
  102. }
  103. var ok bool
  104. hs.clientHello, ok = msg.(*clientHelloMsg)
  105. if !ok {
  106. c.sendAlert(alertUnexpectedMessage)
  107. return false, unexpectedMessageError(hs.clientHello, msg)
  108. }
  109. c.vers, ok = config.mutualVersion(hs.clientHello.vers)
  110. if !ok {
  111. c.sendAlert(alertProtocolVersion)
  112. return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
  113. }
  114. c.haveVers = true
  115. hs.hello = new(serverHelloMsg)
  116. supportedCurve := false
  117. preferredCurves := config.curvePreferences()
  118. Curves:
  119. for _, curve := range hs.clientHello.supportedCurves {
  120. for _, supported := range preferredCurves {
  121. if supported == curve {
  122. supportedCurve = true
  123. break Curves
  124. }
  125. }
  126. }
  127. supportedPointFormat := false
  128. for _, pointFormat := range hs.clientHello.supportedPoints {
  129. if pointFormat == pointFormatUncompressed {
  130. supportedPointFormat = true
  131. break
  132. }
  133. }
  134. hs.ellipticOk = supportedCurve && supportedPointFormat
  135. foundCompression := false
  136. // We only support null compression, so check that the client offered it.
  137. for _, compression := range hs.clientHello.compressionMethods {
  138. if compression == compressionNone {
  139. foundCompression = true
  140. break
  141. }
  142. }
  143. if !foundCompression {
  144. c.sendAlert(alertHandshakeFailure)
  145. return false, errors.New("tls: client does not support uncompressed connections")
  146. }
  147. hs.hello.vers = c.vers
  148. hs.hello.random = make([]byte, 32)
  149. _, err = io.ReadFull(config.rand(), hs.hello.random)
  150. if err != nil {
  151. c.sendAlert(alertInternalError)
  152. return false, err
  153. }
  154. hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
  155. hs.hello.compressionMethod = compressionNone
  156. if len(hs.clientHello.serverName) > 0 {
  157. c.serverName = hs.clientHello.serverName
  158. }
  159. if len(hs.clientHello.alpnProtocols) > 0 {
  160. if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
  161. hs.hello.alpnProtocol = selectedProto
  162. c.clientProtocol = selectedProto
  163. }
  164. } else {
  165. // Although sending an empty NPN extension is reasonable, Firefox has
  166. // had a bug around this. Best to send nothing at all if
  167. // config.NextProtos is empty. See
  168. // https://golang.org/issue/5445.
  169. if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
  170. hs.hello.nextProtoNeg = true
  171. hs.hello.nextProtos = config.NextProtos
  172. }
  173. }
  174. if hs.cert, err = config.getCertificate(&ClientHelloInfo{
  175. CipherSuites: hs.clientHello.cipherSuites,
  176. ServerName: hs.clientHello.serverName,
  177. SupportedCurves: hs.clientHello.supportedCurves,
  178. SupportedPoints: hs.clientHello.supportedPoints,
  179. }); err != nil {
  180. c.sendAlert(alertInternalError)
  181. return false, err
  182. }
  183. if hs.clientHello.scts {
  184. hs.hello.scts = hs.cert.SignedCertificateTimestamps
  185. }
  186. if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
  187. switch priv.Public().(type) {
  188. case *ecdsa.PublicKey:
  189. hs.ecdsaOk = true
  190. case *rsa.PublicKey:
  191. hs.rsaSignOk = true
  192. default:
  193. c.sendAlert(alertInternalError)
  194. return false, fmt.Errorf("crypto/tls: unsupported signing key type (%T)", priv.Public())
  195. }
  196. }
  197. if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
  198. switch priv.Public().(type) {
  199. case *rsa.PublicKey:
  200. hs.rsaDecryptOk = true
  201. default:
  202. c.sendAlert(alertInternalError)
  203. return false, fmt.Errorf("crypto/tls: unsupported decryption key type (%T)", priv.Public())
  204. }
  205. }
  206. if hs.checkForResumption() {
  207. return true, nil
  208. }
  209. var preferenceList, supportedList []uint16
  210. if c.config.PreferServerCipherSuites {
  211. preferenceList = c.config.cipherSuites()
  212. supportedList = hs.clientHello.cipherSuites
  213. } else {
  214. preferenceList = hs.clientHello.cipherSuites
  215. supportedList = c.config.cipherSuites()
  216. }
  217. for _, id := range preferenceList {
  218. if hs.setCipherSuite(id, supportedList, c.vers) {
  219. break
  220. }
  221. }
  222. if hs.suite == nil {
  223. c.sendAlert(alertHandshakeFailure)
  224. return false, errors.New("tls: no cipher suite supported by both client and server")
  225. }
  226. // See https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00.
  227. for _, id := range hs.clientHello.cipherSuites {
  228. if id == TLS_FALLBACK_SCSV {
  229. // The client is doing a fallback connection.
  230. if hs.clientHello.vers < c.config.maxVersion() {
  231. c.sendAlert(alertInappropriateFallback)
  232. return false, errors.New("tls: client using inappropriate protocol fallback")
  233. }
  234. break
  235. }
  236. }
  237. return false, nil
  238. }
  239. // checkForResumption reports whether we should perform resumption on this connection.
  240. func (hs *serverHandshakeState) checkForResumption() bool {
  241. c := hs.c
  242. if c.config.SessionTicketsDisabled {
  243. return false
  244. }
  245. var ok bool
  246. var sessionTicket = append([]uint8{}, hs.clientHello.sessionTicket...)
  247. if hs.sessionState, ok = c.decryptTicket(sessionTicket); !ok {
  248. return false
  249. }
  250. if hs.sessionState.vers > hs.clientHello.vers {
  251. return false
  252. }
  253. if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers {
  254. return false
  255. }
  256. cipherSuiteOk := false
  257. // Check that the client is still offering the ciphersuite in the session.
  258. for _, id := range hs.clientHello.cipherSuites {
  259. if id == hs.sessionState.cipherSuite {
  260. cipherSuiteOk = true
  261. break
  262. }
  263. }
  264. if !cipherSuiteOk {
  265. return false
  266. }
  267. // Check that we also support the ciphersuite from the session.
  268. if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) {
  269. return false
  270. }
  271. sessionHasClientCerts := len(hs.sessionState.certificates) != 0
  272. needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
  273. if needClientCerts && !sessionHasClientCerts {
  274. return false
  275. }
  276. if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
  277. return false
  278. }
  279. return true
  280. }
  281. func (hs *serverHandshakeState) doResumeHandshake() error {
  282. c := hs.c
  283. hs.hello.cipherSuite = hs.suite.id
  284. // We echo the client's session ID in the ServerHello to let it know
  285. // that we're doing a resumption.
  286. hs.hello.sessionId = hs.clientHello.sessionId
  287. hs.hello.ticketSupported = hs.sessionState.usedOldKey
  288. hs.finishedHash.Write(hs.hello.marshal())
  289. c.writeRecord(recordTypeHandshake, hs.hello.marshal())
  290. if len(hs.sessionState.certificates) > 0 {
  291. if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
  292. return err
  293. }
  294. }
  295. hs.masterSecret = hs.sessionState.masterSecret
  296. return nil
  297. }
  298. func (hs *serverHandshakeState) doFullHandshake() error {
  299. config := hs.c.config
  300. c := hs.c
  301. if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
  302. hs.hello.ocspStapling = true
  303. }
  304. hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled
  305. hs.hello.cipherSuite = hs.suite.id
  306. hs.finishedHash.Write(hs.hello.marshal())
  307. c.writeRecord(recordTypeHandshake, hs.hello.marshal())
  308. certMsg := new(certificateMsg)
  309. certMsg.certificates = hs.cert.Certificate
  310. hs.finishedHash.Write(certMsg.marshal())
  311. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  312. if hs.hello.ocspStapling {
  313. certStatus := new(certificateStatusMsg)
  314. certStatus.statusType = statusTypeOCSP
  315. certStatus.response = hs.cert.OCSPStaple
  316. hs.finishedHash.Write(certStatus.marshal())
  317. c.writeRecord(recordTypeHandshake, certStatus.marshal())
  318. }
  319. keyAgreement := hs.suite.ka(c.vers)
  320. skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello)
  321. if err != nil {
  322. c.sendAlert(alertHandshakeFailure)
  323. return err
  324. }
  325. if skx != nil {
  326. hs.finishedHash.Write(skx.marshal())
  327. c.writeRecord(recordTypeHandshake, skx.marshal())
  328. }
  329. if config.ClientAuth >= RequestClientCert {
  330. // Request a client certificate
  331. certReq := new(certificateRequestMsg)
  332. certReq.certificateTypes = []byte{
  333. byte(certTypeRSASign),
  334. byte(certTypeECDSASign),
  335. }
  336. if c.vers >= VersionTLS12 {
  337. certReq.hasSignatureAndHash = true
  338. certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms
  339. }
  340. // An empty list of certificateAuthorities signals to
  341. // the client that it may send any certificate in response
  342. // to our request. When we know the CAs we trust, then
  343. // we can send them down, so that the client can choose
  344. // an appropriate certificate to give to us.
  345. if config.ClientCAs != nil {
  346. certReq.certificateAuthorities = config.ClientCAs.Subjects()
  347. }
  348. hs.finishedHash.Write(certReq.marshal())
  349. c.writeRecord(recordTypeHandshake, certReq.marshal())
  350. }
  351. helloDone := new(serverHelloDoneMsg)
  352. hs.finishedHash.Write(helloDone.marshal())
  353. c.writeRecord(recordTypeHandshake, helloDone.marshal())
  354. var pub crypto.PublicKey // public key for client auth, if any
  355. msg, err := c.readHandshake()
  356. if err != nil {
  357. return err
  358. }
  359. var ok bool
  360. // If we requested a client certificate, then the client must send a
  361. // certificate message, even if it's empty.
  362. if config.ClientAuth >= RequestClientCert {
  363. if certMsg, ok = msg.(*certificateMsg); !ok {
  364. c.sendAlert(alertUnexpectedMessage)
  365. return unexpectedMessageError(certMsg, msg)
  366. }
  367. hs.finishedHash.Write(certMsg.marshal())
  368. if len(certMsg.certificates) == 0 {
  369. // The client didn't actually send a certificate
  370. switch config.ClientAuth {
  371. case RequireAnyClientCert, RequireAndVerifyClientCert:
  372. c.sendAlert(alertBadCertificate)
  373. return errors.New("tls: client didn't provide a certificate")
  374. }
  375. }
  376. pub, err = hs.processCertsFromClient(certMsg.certificates)
  377. if err != nil {
  378. return err
  379. }
  380. msg, err = c.readHandshake()
  381. if err != nil {
  382. return err
  383. }
  384. }
  385. // Get client key exchange
  386. ckx, ok := msg.(*clientKeyExchangeMsg)
  387. if !ok {
  388. c.sendAlert(alertUnexpectedMessage)
  389. return unexpectedMessageError(ckx, msg)
  390. }
  391. hs.finishedHash.Write(ckx.marshal())
  392. // If we received a client cert in response to our certificate request message,
  393. // the client will send us a certificateVerifyMsg immediately after the
  394. // clientKeyExchangeMsg. This message is a digest of all preceding
  395. // handshake-layer messages that is signed using the private key corresponding
  396. // to the client's certificate. This allows us to verify that the client is in
  397. // possession of the private key of the certificate.
  398. if len(c.peerCertificates) > 0 {
  399. msg, err = c.readHandshake()
  400. if err != nil {
  401. return err
  402. }
  403. certVerify, ok := msg.(*certificateVerifyMsg)
  404. if !ok {
  405. c.sendAlert(alertUnexpectedMessage)
  406. return unexpectedMessageError(certVerify, msg)
  407. }
  408. switch key := pub.(type) {
  409. case *ecdsa.PublicKey:
  410. ecdsaSig := new(ecdsaSignature)
  411. if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
  412. break
  413. }
  414. if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
  415. err = errors.New("ECDSA signature contained zero or negative values")
  416. break
  417. }
  418. digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
  419. if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
  420. err = errors.New("ECDSA verification failure")
  421. break
  422. }
  423. case *rsa.PublicKey:
  424. digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA)
  425. err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
  426. }
  427. if err != nil {
  428. c.sendAlert(alertBadCertificate)
  429. return errors.New("could not validate signature of connection nonces: " + err.Error())
  430. }
  431. hs.finishedHash.Write(certVerify.marshal())
  432. }
  433. preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
  434. if err != nil {
  435. c.sendAlert(alertHandshakeFailure)
  436. return err
  437. }
  438. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite.tls12Hash, preMasterSecret, hs.clientHello.random, hs.hello.random)
  439. return nil
  440. }
  441. func (hs *serverHandshakeState) establishKeys() error {
  442. c := hs.c
  443. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  444. keysFromMasterSecret(c.vers, hs.suite.tls12Hash, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  445. var clientCipher, serverCipher interface{}
  446. var clientHash, serverHash macFunction
  447. if hs.suite.aead == nil {
  448. clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
  449. clientHash = hs.suite.mac(c.vers, clientMAC)
  450. serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
  451. serverHash = hs.suite.mac(c.vers, serverMAC)
  452. } else {
  453. clientCipher = hs.suite.aead(clientKey, clientIV)
  454. serverCipher = hs.suite.aead(serverKey, serverIV)
  455. }
  456. c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
  457. c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
  458. return nil
  459. }
  460. func (hs *serverHandshakeState) readFinished(out []byte) error {
  461. c := hs.c
  462. c.readRecord(recordTypeChangeCipherSpec)
  463. if err := c.in.error(); err != nil {
  464. return err
  465. }
  466. if hs.hello.nextProtoNeg {
  467. msg, err := c.readHandshake()
  468. if err != nil {
  469. return err
  470. }
  471. nextProto, ok := msg.(*nextProtoMsg)
  472. if !ok {
  473. c.sendAlert(alertUnexpectedMessage)
  474. return unexpectedMessageError(nextProto, msg)
  475. }
  476. hs.finishedHash.Write(nextProto.marshal())
  477. c.clientProtocol = nextProto.proto
  478. }
  479. msg, err := c.readHandshake()
  480. if err != nil {
  481. return err
  482. }
  483. clientFinished, ok := msg.(*finishedMsg)
  484. if !ok {
  485. c.sendAlert(alertUnexpectedMessage)
  486. return unexpectedMessageError(clientFinished, msg)
  487. }
  488. verify := hs.finishedHash.clientSum(hs.masterSecret)
  489. if len(verify) != len(clientFinished.verifyData) ||
  490. subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
  491. c.sendAlert(alertHandshakeFailure)
  492. return errors.New("tls: client's Finished message is incorrect")
  493. }
  494. hs.finishedHash.Write(clientFinished.marshal())
  495. copy(out, verify)
  496. return nil
  497. }
  498. func (hs *serverHandshakeState) sendSessionTicket() error {
  499. if !hs.hello.ticketSupported {
  500. return nil
  501. }
  502. c := hs.c
  503. m := new(newSessionTicketMsg)
  504. var err error
  505. state := sessionState{
  506. vers: c.vers,
  507. cipherSuite: hs.suite.id,
  508. masterSecret: hs.masterSecret,
  509. certificates: hs.certsFromClient,
  510. }
  511. m.ticket, err = c.encryptTicket(&state)
  512. if err != nil {
  513. return err
  514. }
  515. hs.finishedHash.Write(m.marshal())
  516. c.writeRecord(recordTypeHandshake, m.marshal())
  517. return nil
  518. }
  519. func (hs *serverHandshakeState) sendFinished(out []byte) error {
  520. c := hs.c
  521. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  522. finished := new(finishedMsg)
  523. finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
  524. hs.finishedHash.Write(finished.marshal())
  525. c.writeRecord(recordTypeHandshake, finished.marshal())
  526. c.cipherSuite = hs.suite.id
  527. copy(out, finished.verifyData)
  528. return nil
  529. }
  530. // processCertsFromClient takes a chain of client certificates either from a
  531. // Certificates message or from a sessionState and verifies them. It returns
  532. // the public key of the leaf certificate.
  533. func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
  534. c := hs.c
  535. hs.certsFromClient = certificates
  536. certs := make([]*x509.Certificate, len(certificates))
  537. var err error
  538. for i, asn1Data := range certificates {
  539. if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
  540. c.sendAlert(alertBadCertificate)
  541. return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
  542. }
  543. }
  544. if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
  545. opts := x509.VerifyOptions{
  546. Roots: c.config.ClientCAs,
  547. CurrentTime: c.config.time(),
  548. Intermediates: x509.NewCertPool(),
  549. KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
  550. }
  551. for _, cert := range certs[1:] {
  552. opts.Intermediates.AddCert(cert)
  553. }
  554. chains, err := certs[0].Verify(opts)
  555. if err != nil {
  556. c.sendAlert(alertBadCertificate)
  557. return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
  558. }
  559. ok := false
  560. for _, ku := range certs[0].ExtKeyUsage {
  561. if ku == x509.ExtKeyUsageClientAuth {
  562. ok = true
  563. break
  564. }
  565. }
  566. if !ok {
  567. c.sendAlert(alertHandshakeFailure)
  568. return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
  569. }
  570. c.verifiedChains = chains
  571. }
  572. if len(certs) > 0 {
  573. var pub crypto.PublicKey
  574. switch key := certs[0].PublicKey.(type) {
  575. case *ecdsa.PublicKey, *rsa.PublicKey:
  576. pub = key
  577. default:
  578. c.sendAlert(alertUnsupportedCertificate)
  579. return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
  580. }
  581. c.peerCertificates = certs
  582. return pub, nil
  583. }
  584. return nil, nil
  585. }
  586. // setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState
  587. // suite if that cipher suite is acceptable to use.
  588. // It returns a bool indicating if the suite was set.
  589. func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool {
  590. for _, supported := range supportedCipherSuites {
  591. if id == supported {
  592. var candidate *cipherSuite
  593. for _, s := range cipherSuites {
  594. if s.id == id {
  595. candidate = s
  596. break
  597. }
  598. }
  599. if candidate == nil {
  600. continue
  601. }
  602. // Don't select a ciphersuite which we can't
  603. // support for this client.
  604. if candidate.flags&suiteECDHE != 0 {
  605. if !hs.ellipticOk {
  606. continue
  607. }
  608. if candidate.flags&suiteECDSA != 0 {
  609. if !hs.ecdsaOk {
  610. continue
  611. }
  612. } else if !hs.rsaSignOk {
  613. continue
  614. }
  615. } else if !hs.rsaDecryptOk {
  616. continue
  617. }
  618. if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
  619. continue
  620. }
  621. hs.suite = candidate
  622. return true
  623. }
  624. }
  625. return false
  626. }