handshake_client.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  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/ecdsa"
  9. "crypto/rsa"
  10. "crypto/subtle"
  11. "crypto/x509"
  12. "errors"
  13. "fmt"
  14. "io"
  15. "net"
  16. "strconv"
  17. )
  18. type clientHandshakeState struct {
  19. c *Conn
  20. serverHello *serverHelloMsg
  21. hello *clientHelloMsg
  22. suite *cipherSuite
  23. finishedHash finishedHash
  24. masterSecret []byte
  25. session *ClientSessionState
  26. }
  27. func (c *Conn) clientHandshake() error {
  28. if c.config == nil {
  29. c.config = defaultConfig()
  30. }
  31. if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
  32. return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
  33. }
  34. nextProtosLength := 0
  35. for _, proto := range c.config.NextProtos {
  36. if l := len(proto); l == 0 || l > 255 {
  37. return errors.New("tls: invalid NextProtos value")
  38. } else {
  39. nextProtosLength += 1 + l
  40. }
  41. }
  42. if nextProtosLength > 0xffff {
  43. return errors.New("tls: NextProtos values too large")
  44. }
  45. sni := c.config.ServerName
  46. // IP address literals are not permitted as SNI values. See
  47. // https://tools.ietf.org/html/rfc6066#section-3.
  48. if net.ParseIP(sni) != nil {
  49. sni = ""
  50. }
  51. hello := &clientHelloMsg{
  52. vers: c.config.maxVersion(),
  53. compressionMethods: []uint8{compressionNone},
  54. random: make([]byte, 32),
  55. ocspStapling: true,
  56. scts: true,
  57. serverName: sni,
  58. supportedCurves: c.config.curvePreferences(),
  59. supportedPoints: []uint8{pointFormatUncompressed},
  60. nextProtoNeg: len(c.config.NextProtos) > 0,
  61. secureRenegotiation: true,
  62. alpnProtocols: c.config.NextProtos,
  63. }
  64. possibleCipherSuites := c.config.cipherSuites()
  65. hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
  66. NextCipherSuite:
  67. for _, suiteId := range possibleCipherSuites {
  68. for _, suite := range cipherSuites {
  69. if suite.id != suiteId {
  70. continue
  71. }
  72. // Don't advertise TLS 1.2-only cipher suites unless
  73. // we're attempting TLS 1.2.
  74. if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
  75. continue
  76. }
  77. hello.cipherSuites = append(hello.cipherSuites, suiteId)
  78. continue NextCipherSuite
  79. }
  80. }
  81. _, err := io.ReadFull(c.config.rand(), hello.random)
  82. if err != nil {
  83. c.sendAlert(alertInternalError)
  84. return errors.New("tls: short read from Rand: " + err.Error())
  85. }
  86. if hello.vers >= VersionTLS12 {
  87. hello.signatureAndHashes = supportedSignatureAlgorithms
  88. }
  89. var session *ClientSessionState
  90. var cacheKey string
  91. sessionCache := c.config.ClientSessionCache
  92. if c.config.SessionTicketsDisabled {
  93. sessionCache = nil
  94. }
  95. if sessionCache != nil {
  96. hello.ticketSupported = true
  97. // Try to resume a previously negotiated TLS session, if
  98. // available.
  99. cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
  100. candidateSession, ok := sessionCache.Get(cacheKey)
  101. if ok {
  102. // Check that the ciphersuite/version used for the
  103. // previous session are still valid.
  104. cipherSuiteOk := false
  105. for _, id := range hello.cipherSuites {
  106. if id == candidateSession.cipherSuite {
  107. cipherSuiteOk = true
  108. break
  109. }
  110. }
  111. versOk := candidateSession.vers >= c.config.minVersion() &&
  112. candidateSession.vers <= c.config.maxVersion()
  113. if versOk && cipherSuiteOk {
  114. session = candidateSession
  115. }
  116. }
  117. }
  118. if session != nil {
  119. hello.sessionTicket = session.sessionTicket
  120. // A random session ID is used to detect when the
  121. // server accepted the ticket and is resuming a session
  122. // (see RFC 5077).
  123. hello.sessionId = make([]byte, 16)
  124. if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
  125. c.sendAlert(alertInternalError)
  126. return errors.New("tls: short read from Rand: " + err.Error())
  127. }
  128. }
  129. c.writeRecord(recordTypeHandshake, hello.marshal())
  130. msg, err := c.readHandshake()
  131. if err != nil {
  132. return err
  133. }
  134. serverHello, ok := msg.(*serverHelloMsg)
  135. if !ok {
  136. c.sendAlert(alertUnexpectedMessage)
  137. return unexpectedMessageError(serverHello, msg)
  138. }
  139. vers, ok := c.config.mutualVersion(serverHello.vers)
  140. if !ok || vers < VersionTLS10 {
  141. // TLS 1.0 is the minimum version supported as a client.
  142. c.sendAlert(alertProtocolVersion)
  143. return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
  144. }
  145. c.vers = vers
  146. c.haveVers = true
  147. suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite)
  148. if suite == nil {
  149. c.sendAlert(alertHandshakeFailure)
  150. return errors.New("tls: server chose an unconfigured cipher suite")
  151. }
  152. hs := &clientHandshakeState{
  153. c: c,
  154. serverHello: serverHello,
  155. hello: hello,
  156. suite: suite,
  157. finishedHash: newFinishedHash(c.vers, suite),
  158. session: session,
  159. }
  160. isResume, err := hs.processServerHello()
  161. if err != nil {
  162. return err
  163. }
  164. // No signatures of the handshake are needed in a resumption.
  165. // Otherwise, in a full handshake, if we don't have any certificates
  166. // configured then we will never send a CertificateVerify message and
  167. // thus no signatures are needed in that case either.
  168. if isResume || len(c.config.Certificates) == 0 {
  169. hs.finishedHash.discardHandshakeBuffer()
  170. }
  171. hs.finishedHash.Write(hs.hello.marshal())
  172. hs.finishedHash.Write(hs.serverHello.marshal())
  173. if isResume {
  174. if err := hs.establishKeys(); err != nil {
  175. return err
  176. }
  177. if err := hs.readSessionTicket(); err != nil {
  178. return err
  179. }
  180. if err := hs.readFinished(c.firstFinished[:]); err != nil {
  181. return err
  182. }
  183. if err := hs.sendFinished(nil); err != nil {
  184. return err
  185. }
  186. } else {
  187. if err := hs.doFullHandshake(); err != nil {
  188. return err
  189. }
  190. if err := hs.establishKeys(); err != nil {
  191. return err
  192. }
  193. if err := hs.sendFinished(c.firstFinished[:]); err != nil {
  194. return err
  195. }
  196. if err := hs.readSessionTicket(); err != nil {
  197. return err
  198. }
  199. if err := hs.readFinished(nil); err != nil {
  200. return err
  201. }
  202. }
  203. if sessionCache != nil && hs.session != nil && session != hs.session {
  204. sessionCache.Put(cacheKey, hs.session)
  205. }
  206. c.didResume = isResume
  207. c.handshakeComplete = true
  208. c.cipherSuite = suite.id
  209. return nil
  210. }
  211. func (hs *clientHandshakeState) doFullHandshake() error {
  212. c := hs.c
  213. msg, err := c.readHandshake()
  214. if err != nil {
  215. return err
  216. }
  217. certMsg, ok := msg.(*certificateMsg)
  218. if !ok || len(certMsg.certificates) == 0 {
  219. c.sendAlert(alertUnexpectedMessage)
  220. return unexpectedMessageError(certMsg, msg)
  221. }
  222. hs.finishedHash.Write(certMsg.marshal())
  223. certs := make([]*x509.Certificate, len(certMsg.certificates))
  224. for i, asn1Data := range certMsg.certificates {
  225. cert, err := x509.ParseCertificate(asn1Data)
  226. if err != nil {
  227. c.sendAlert(alertBadCertificate)
  228. return errors.New("tls: failed to parse certificate from server: " + err.Error())
  229. }
  230. certs[i] = cert
  231. }
  232. if !c.config.InsecureSkipVerify {
  233. opts := x509.VerifyOptions{
  234. Roots: c.config.RootCAs,
  235. CurrentTime: c.config.time(),
  236. DNSName: c.config.ServerName,
  237. Intermediates: x509.NewCertPool(),
  238. }
  239. for i, cert := range certs {
  240. if i == 0 {
  241. continue
  242. }
  243. opts.Intermediates.AddCert(cert)
  244. }
  245. c.verifiedChains, err = certs[0].Verify(opts)
  246. if err != nil {
  247. c.sendAlert(alertBadCertificate)
  248. return err
  249. }
  250. }
  251. switch certs[0].PublicKey.(type) {
  252. case *rsa.PublicKey, *ecdsa.PublicKey:
  253. break
  254. default:
  255. c.sendAlert(alertUnsupportedCertificate)
  256. return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
  257. }
  258. c.peerCertificates = certs
  259. if hs.serverHello.ocspStapling {
  260. msg, err = c.readHandshake()
  261. if err != nil {
  262. return err
  263. }
  264. cs, ok := msg.(*certificateStatusMsg)
  265. if !ok {
  266. c.sendAlert(alertUnexpectedMessage)
  267. return unexpectedMessageError(cs, msg)
  268. }
  269. hs.finishedHash.Write(cs.marshal())
  270. if cs.statusType == statusTypeOCSP {
  271. c.ocspResponse = cs.response
  272. }
  273. }
  274. msg, err = c.readHandshake()
  275. if err != nil {
  276. return err
  277. }
  278. keyAgreement := hs.suite.ka(c.vers)
  279. skx, ok := msg.(*serverKeyExchangeMsg)
  280. if ok {
  281. hs.finishedHash.Write(skx.marshal())
  282. err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
  283. if err != nil {
  284. c.sendAlert(alertUnexpectedMessage)
  285. return err
  286. }
  287. msg, err = c.readHandshake()
  288. if err != nil {
  289. return err
  290. }
  291. }
  292. var chainToSend *Certificate
  293. var certRequested bool
  294. certReq, ok := msg.(*certificateRequestMsg)
  295. if ok {
  296. certRequested = true
  297. // RFC 4346 on the certificateAuthorities field:
  298. // A list of the distinguished names of acceptable certificate
  299. // authorities. These distinguished names may specify a desired
  300. // distinguished name for a root CA or for a subordinate CA;
  301. // thus, this message can be used to describe both known roots
  302. // and a desired authorization space. If the
  303. // certificate_authorities list is empty then the client MAY
  304. // send any certificate of the appropriate
  305. // ClientCertificateType, unless there is some external
  306. // arrangement to the contrary.
  307. hs.finishedHash.Write(certReq.marshal())
  308. var rsaAvail, ecdsaAvail bool
  309. for _, certType := range certReq.certificateTypes {
  310. switch certType {
  311. case certTypeRSASign:
  312. rsaAvail = true
  313. case certTypeECDSASign:
  314. ecdsaAvail = true
  315. }
  316. }
  317. // We need to search our list of client certs for one
  318. // where SignatureAlgorithm is acceptable to the server and the
  319. // Issuer is in certReq.certificateAuthorities
  320. findCert:
  321. for i, chain := range c.config.Certificates {
  322. if !rsaAvail && !ecdsaAvail {
  323. continue
  324. }
  325. for j, cert := range chain.Certificate {
  326. x509Cert := chain.Leaf
  327. // parse the certificate if this isn't the leaf
  328. // node, or if chain.Leaf was nil
  329. if j != 0 || x509Cert == nil {
  330. if x509Cert, err = x509.ParseCertificate(cert); err != nil {
  331. c.sendAlert(alertInternalError)
  332. return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
  333. }
  334. }
  335. switch {
  336. case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
  337. case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
  338. default:
  339. continue findCert
  340. }
  341. if len(certReq.certificateAuthorities) == 0 {
  342. // they gave us an empty list, so just take the
  343. // first cert from c.config.Certificates
  344. chainToSend = &chain
  345. break findCert
  346. }
  347. for _, ca := range certReq.certificateAuthorities {
  348. if bytes.Equal(x509Cert.RawIssuer, ca) {
  349. chainToSend = &chain
  350. break findCert
  351. }
  352. }
  353. }
  354. }
  355. msg, err = c.readHandshake()
  356. if err != nil {
  357. return err
  358. }
  359. }
  360. shd, ok := msg.(*serverHelloDoneMsg)
  361. if !ok {
  362. c.sendAlert(alertUnexpectedMessage)
  363. return unexpectedMessageError(shd, msg)
  364. }
  365. hs.finishedHash.Write(shd.marshal())
  366. // If the server requested a certificate then we have to send a
  367. // Certificate message, even if it's empty because we don't have a
  368. // certificate to send.
  369. if certRequested {
  370. certMsg = new(certificateMsg)
  371. if chainToSend != nil {
  372. certMsg.certificates = chainToSend.Certificate
  373. }
  374. hs.finishedHash.Write(certMsg.marshal())
  375. c.writeRecord(recordTypeHandshake, certMsg.marshal())
  376. }
  377. preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
  378. if err != nil {
  379. c.sendAlert(alertInternalError)
  380. return err
  381. }
  382. if ckx != nil {
  383. hs.finishedHash.Write(ckx.marshal())
  384. c.writeRecord(recordTypeHandshake, ckx.marshal())
  385. }
  386. if chainToSend != nil {
  387. certVerify := &certificateVerifyMsg{
  388. hasSignatureAndHash: c.vers >= VersionTLS12,
  389. }
  390. key, ok := chainToSend.PrivateKey.(crypto.Signer)
  391. if !ok {
  392. c.sendAlert(alertInternalError)
  393. return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
  394. }
  395. var signatureType uint8
  396. switch key.Public().(type) {
  397. case *ecdsa.PublicKey:
  398. signatureType = signatureECDSA
  399. case *rsa.PublicKey:
  400. signatureType = signatureRSA
  401. default:
  402. c.sendAlert(alertInternalError)
  403. return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
  404. }
  405. certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureType)
  406. if err != nil {
  407. c.sendAlert(alertInternalError)
  408. return err
  409. }
  410. digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
  411. if err != nil {
  412. c.sendAlert(alertInternalError)
  413. return err
  414. }
  415. certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
  416. if err != nil {
  417. c.sendAlert(alertInternalError)
  418. return err
  419. }
  420. hs.finishedHash.Write(certVerify.marshal())
  421. c.writeRecord(recordTypeHandshake, certVerify.marshal())
  422. }
  423. hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
  424. hs.finishedHash.discardHandshakeBuffer()
  425. return nil
  426. }
  427. func (hs *clientHandshakeState) establishKeys() error {
  428. c := hs.c
  429. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  430. keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
  431. var clientCipher, serverCipher interface{}
  432. var clientHash, serverHash macFunction
  433. if hs.suite.cipher != nil {
  434. clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
  435. clientHash = hs.suite.mac(c.vers, clientMAC)
  436. serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
  437. serverHash = hs.suite.mac(c.vers, serverMAC)
  438. } else {
  439. clientCipher = hs.suite.aead(clientKey, clientIV)
  440. serverCipher = hs.suite.aead(serverKey, serverIV)
  441. }
  442. c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
  443. c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
  444. return nil
  445. }
  446. func (hs *clientHandshakeState) serverResumedSession() bool {
  447. // If the server responded with the same sessionId then it means the
  448. // sessionTicket is being used to resume a TLS session.
  449. return hs.session != nil && hs.hello.sessionId != nil &&
  450. bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
  451. }
  452. func (hs *clientHandshakeState) processServerHello() (bool, error) {
  453. c := hs.c
  454. if hs.serverHello.compressionMethod != compressionNone {
  455. c.sendAlert(alertUnexpectedMessage)
  456. return false, errors.New("tls: server selected unsupported compression format")
  457. }
  458. clientDidNPN := hs.hello.nextProtoNeg
  459. clientDidALPN := len(hs.hello.alpnProtocols) > 0
  460. serverHasNPN := hs.serverHello.nextProtoNeg
  461. serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
  462. if !clientDidNPN && serverHasNPN {
  463. c.sendAlert(alertHandshakeFailure)
  464. return false, errors.New("server advertised unrequested NPN extension")
  465. }
  466. if !clientDidALPN && serverHasALPN {
  467. c.sendAlert(alertHandshakeFailure)
  468. return false, errors.New("server advertised unrequested ALPN extension")
  469. }
  470. if serverHasNPN && serverHasALPN {
  471. c.sendAlert(alertHandshakeFailure)
  472. return false, errors.New("server advertised both NPN and ALPN extensions")
  473. }
  474. if serverHasALPN {
  475. c.clientProtocol = hs.serverHello.alpnProtocol
  476. c.clientProtocolFallback = false
  477. }
  478. c.scts = hs.serverHello.scts
  479. if hs.serverResumedSession() {
  480. // Restore masterSecret and peerCerts from previous state
  481. hs.masterSecret = hs.session.masterSecret
  482. c.peerCertificates = hs.session.serverCertificates
  483. c.verifiedChains = hs.session.verifiedChains
  484. return true, nil
  485. }
  486. return false, nil
  487. }
  488. func (hs *clientHandshakeState) readFinished(out []byte) error {
  489. c := hs.c
  490. c.readRecord(recordTypeChangeCipherSpec)
  491. if err := c.in.error(); err != nil {
  492. return err
  493. }
  494. msg, err := c.readHandshake()
  495. if err != nil {
  496. return err
  497. }
  498. serverFinished, ok := msg.(*finishedMsg)
  499. if !ok {
  500. c.sendAlert(alertUnexpectedMessage)
  501. return unexpectedMessageError(serverFinished, msg)
  502. }
  503. verify := hs.finishedHash.serverSum(hs.masterSecret)
  504. if len(verify) != len(serverFinished.verifyData) ||
  505. subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
  506. c.sendAlert(alertHandshakeFailure)
  507. return errors.New("tls: server's Finished message was incorrect")
  508. }
  509. hs.finishedHash.Write(serverFinished.marshal())
  510. copy(out, verify)
  511. return nil
  512. }
  513. func (hs *clientHandshakeState) readSessionTicket() error {
  514. if !hs.serverHello.ticketSupported {
  515. return nil
  516. }
  517. c := hs.c
  518. msg, err := c.readHandshake()
  519. if err != nil {
  520. return err
  521. }
  522. sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
  523. if !ok {
  524. c.sendAlert(alertUnexpectedMessage)
  525. return unexpectedMessageError(sessionTicketMsg, msg)
  526. }
  527. hs.finishedHash.Write(sessionTicketMsg.marshal())
  528. hs.session = &ClientSessionState{
  529. sessionTicket: sessionTicketMsg.ticket,
  530. vers: c.vers,
  531. cipherSuite: hs.suite.id,
  532. masterSecret: hs.masterSecret,
  533. serverCertificates: c.peerCertificates,
  534. verifiedChains: c.verifiedChains,
  535. }
  536. return nil
  537. }
  538. func (hs *clientHandshakeState) sendFinished(out []byte) error {
  539. c := hs.c
  540. c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
  541. if hs.serverHello.nextProtoNeg {
  542. nextProto := new(nextProtoMsg)
  543. proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
  544. nextProto.proto = proto
  545. c.clientProtocol = proto
  546. c.clientProtocolFallback = fallback
  547. hs.finishedHash.Write(nextProto.marshal())
  548. c.writeRecord(recordTypeHandshake, nextProto.marshal())
  549. }
  550. finished := new(finishedMsg)
  551. finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
  552. hs.finishedHash.Write(finished.marshal())
  553. c.writeRecord(recordTypeHandshake, finished.marshal())
  554. copy(out, finished.verifyData)
  555. return nil
  556. }
  557. // clientSessionCacheKey returns a key used to cache sessionTickets that could
  558. // be used to resume previously negotiated TLS sessions with a server.
  559. func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
  560. if len(config.ServerName) > 0 {
  561. return config.ServerName
  562. }
  563. return serverAddr.String()
  564. }
  565. // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
  566. // given list of possible protocols and a list of the preference order. The
  567. // first list must not be empty. It returns the resulting protocol and flag
  568. // indicating if the fallback case was reached.
  569. func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
  570. for _, s := range preferenceProtos {
  571. for _, c := range protos {
  572. if s == c {
  573. return s, false
  574. }
  575. }
  576. }
  577. return protos[0], true
  578. }