選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

handshake_server.go 19 KiB

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