Source file
src/crypto/tls/handshake_client.go
1
2
3
4
5 package tls
6
7 import (
8 "bytes"
9 "crypto"
10 "crypto/ecdsa"
11 "crypto/rsa"
12 "crypto/subtle"
13 "crypto/x509"
14 "errors"
15 "fmt"
16 "io"
17 "net"
18 "strconv"
19 "strings"
20 )
21
22 type clientHandshakeState struct {
23 c *Conn
24 serverHello *serverHelloMsg
25 hello *clientHelloMsg
26 suite *cipherSuite
27 finishedHash finishedHash
28 masterSecret []byte
29 session *ClientSessionState
30 }
31
32 func makeClientHello(config *Config) (*clientHelloMsg, error) {
33 if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
34 return nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
35 }
36
37 nextProtosLength := 0
38 for _, proto := range config.NextProtos {
39 if l := len(proto); l == 0 || l > 255 {
40 return nil, errors.New("tls: invalid NextProtos value")
41 } else {
42 nextProtosLength += 1 + l
43 }
44 }
45
46 if nextProtosLength > 0xffff {
47 return nil, errors.New("tls: NextProtos values too large")
48 }
49
50 hello := &clientHelloMsg{
51 vers: config.maxVersion(),
52 compressionMethods: []uint8{compressionNone},
53 random: make([]byte, 32),
54 ocspStapling: true,
55 scts: true,
56 serverName: hostnameInSNI(config.ServerName),
57 supportedCurves: config.curvePreferences(),
58 supportedPoints: []uint8{pointFormatUncompressed},
59 nextProtoNeg: len(config.NextProtos) > 0,
60 secureRenegotiationSupported: true,
61 alpnProtocols: config.NextProtos,
62 }
63 possibleCipherSuites := config.cipherSuites()
64 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
65
66 NextCipherSuite:
67 for _, suiteId := range possibleCipherSuites {
68 for _, suite := range cipherSuites {
69 if suite.id != suiteId {
70 continue
71 }
72
73
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
82 _, err := io.ReadFull(config.rand(), hello.random)
83 if err != nil {
84 return nil, errors.New("tls: short read from Rand: " + err.Error())
85 }
86
87 if hello.vers >= VersionTLS12 {
88 hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
89 }
90
91 return hello, nil
92 }
93
94
95 func (c *Conn) clientHandshake() error {
96 if c.config == nil {
97 c.config = defaultConfig()
98 }
99
100
101
102 c.didResume = false
103
104 hello, err := makeClientHello(c.config)
105 if err != nil {
106 return err
107 }
108
109 if c.handshakes > 0 {
110 hello.secureRenegotiation = c.clientFinished[:]
111 }
112
113 var session *ClientSessionState
114 var cacheKey string
115 sessionCache := c.config.ClientSessionCache
116 if c.config.SessionTicketsDisabled {
117 sessionCache = nil
118 }
119
120 if sessionCache != nil {
121 hello.ticketSupported = true
122 }
123
124
125
126
127 if sessionCache != nil && c.handshakes == 0 {
128
129
130 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
131 candidateSession, ok := sessionCache.Get(cacheKey)
132 if ok {
133
134
135 cipherSuiteOk := false
136 for _, id := range hello.cipherSuites {
137 if id == candidateSession.cipherSuite {
138 cipherSuiteOk = true
139 break
140 }
141 }
142
143 versOk := candidateSession.vers >= c.config.minVersion() &&
144 candidateSession.vers <= c.config.maxVersion()
145 if versOk && cipherSuiteOk {
146 session = candidateSession
147 }
148 }
149 }
150
151 if session != nil {
152 hello.sessionTicket = session.sessionTicket
153
154
155
156 hello.sessionId = make([]byte, 16)
157 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
158 return errors.New("tls: short read from Rand: " + err.Error())
159 }
160 }
161
162 hs := &clientHandshakeState{
163 c: c,
164 hello: hello,
165 session: session,
166 }
167
168 if err = hs.handshake(); err != nil {
169 return err
170 }
171
172
173
174 if sessionCache != nil && hs.session != nil && session != hs.session {
175 sessionCache.Put(cacheKey, hs.session)
176 }
177
178 return nil
179 }
180
181
182
183 func (hs *clientHandshakeState) handshake() error {
184 c := hs.c
185
186
187 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
188 return err
189 }
190
191 msg, err := c.readHandshake()
192 if err != nil {
193 return err
194 }
195
196 var ok bool
197 if hs.serverHello, ok = msg.(*serverHelloMsg); !ok {
198 c.sendAlert(alertUnexpectedMessage)
199 return unexpectedMessageError(hs.serverHello, msg)
200 }
201
202 if err = hs.pickTLSVersion(); err != nil {
203 return err
204 }
205
206 if err = hs.pickCipherSuite(); err != nil {
207 return err
208 }
209
210 isResume, err := hs.processServerHello()
211 if err != nil {
212 return err
213 }
214
215 hs.finishedHash = newFinishedHash(c.vers, hs.suite)
216
217
218
219
220
221 if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
222 hs.finishedHash.discardHandshakeBuffer()
223 }
224
225 hs.finishedHash.Write(hs.hello.marshal())
226 hs.finishedHash.Write(hs.serverHello.marshal())
227
228 c.buffering = true
229 if isResume {
230 if err := hs.establishKeys(); err != nil {
231 return err
232 }
233 if err := hs.readSessionTicket(); err != nil {
234 return err
235 }
236 if err := hs.readFinished(c.serverFinished[:]); err != nil {
237 return err
238 }
239 c.clientFinishedIsFirst = false
240 if err := hs.sendFinished(c.clientFinished[:]); err != nil {
241 return err
242 }
243 if _, err := c.flush(); err != nil {
244 return err
245 }
246 } else {
247 if err := hs.doFullHandshake(); err != nil {
248 return err
249 }
250 if err := hs.establishKeys(); err != nil {
251 return err
252 }
253 if err := hs.sendFinished(c.clientFinished[:]); err != nil {
254 return err
255 }
256 if _, err := c.flush(); err != nil {
257 return err
258 }
259 c.clientFinishedIsFirst = true
260 if err := hs.readSessionTicket(); err != nil {
261 return err
262 }
263 if err := hs.readFinished(c.serverFinished[:]); err != nil {
264 return err
265 }
266 }
267
268 c.didResume = isResume
269 c.handshakeComplete = true
270
271 return nil
272 }
273
274 func (hs *clientHandshakeState) pickTLSVersion() error {
275 vers, ok := hs.c.config.mutualVersion(hs.serverHello.vers)
276 if !ok || vers < VersionTLS10 {
277
278 hs.c.sendAlert(alertProtocolVersion)
279 return fmt.Errorf("tls: server selected unsupported protocol version %x", hs.serverHello.vers)
280 }
281
282 hs.c.vers = vers
283 hs.c.haveVers = true
284
285 return nil
286 }
287
288 func (hs *clientHandshakeState) pickCipherSuite() error {
289 if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
290 hs.c.sendAlert(alertHandshakeFailure)
291 return errors.New("tls: server chose an unconfigured cipher suite")
292 }
293
294 hs.c.cipherSuite = hs.suite.id
295 return nil
296 }
297
298 func (hs *clientHandshakeState) doFullHandshake() error {
299 c := hs.c
300
301 msg, err := c.readHandshake()
302 if err != nil {
303 return err
304 }
305 certMsg, ok := msg.(*certificateMsg)
306 if !ok || len(certMsg.certificates) == 0 {
307 c.sendAlert(alertUnexpectedMessage)
308 return unexpectedMessageError(certMsg, msg)
309 }
310 hs.finishedHash.Write(certMsg.marshal())
311
312 if c.handshakes == 0 {
313
314
315 certs := make([]*x509.Certificate, len(certMsg.certificates))
316 for i, asn1Data := range certMsg.certificates {
317 cert, err := x509.ParseCertificate(asn1Data)
318 if err != nil {
319 c.sendAlert(alertBadCertificate)
320 return errors.New("tls: failed to parse certificate from server: " + err.Error())
321 }
322 certs[i] = cert
323 }
324
325 if !c.config.InsecureSkipVerify {
326 opts := x509.VerifyOptions{
327 Roots: c.config.RootCAs,
328 CurrentTime: c.config.time(),
329 DNSName: c.config.ServerName,
330 Intermediates: x509.NewCertPool(),
331 }
332
333 for i, cert := range certs {
334 if i == 0 {
335 continue
336 }
337 opts.Intermediates.AddCert(cert)
338 }
339 c.verifiedChains, err = certs[0].Verify(opts)
340 if err != nil {
341 c.sendAlert(alertBadCertificate)
342 return err
343 }
344 }
345
346 if c.config.VerifyPeerCertificate != nil {
347 if err := c.config.VerifyPeerCertificate(certMsg.certificates, c.verifiedChains); err != nil {
348 c.sendAlert(alertBadCertificate)
349 return err
350 }
351 }
352
353 switch certs[0].PublicKey.(type) {
354 case *rsa.PublicKey, *ecdsa.PublicKey:
355 break
356 default:
357 c.sendAlert(alertUnsupportedCertificate)
358 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
359 }
360
361 c.peerCertificates = certs
362 } else {
363
364
365
366
367
368
369 if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
370 c.sendAlert(alertBadCertificate)
371 return errors.New("tls: server's identity changed during renegotiation")
372 }
373 }
374
375 msg, err = c.readHandshake()
376 if err != nil {
377 return err
378 }
379
380 cs, ok := msg.(*certificateStatusMsg)
381 if ok {
382
383
384
385 if !hs.serverHello.ocspStapling {
386
387
388
389
390 c.sendAlert(alertUnexpectedMessage)
391 return errors.New("tls: received unexpected CertificateStatus message")
392 }
393 hs.finishedHash.Write(cs.marshal())
394
395 if cs.statusType == statusTypeOCSP {
396 c.ocspResponse = cs.response
397 }
398
399 msg, err = c.readHandshake()
400 if err != nil {
401 return err
402 }
403 }
404
405 keyAgreement := hs.suite.ka(c.vers)
406
407 skx, ok := msg.(*serverKeyExchangeMsg)
408 if ok {
409 hs.finishedHash.Write(skx.marshal())
410 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
411 if err != nil {
412 c.sendAlert(alertUnexpectedMessage)
413 return err
414 }
415
416 msg, err = c.readHandshake()
417 if err != nil {
418 return err
419 }
420 }
421
422 var chainToSend *Certificate
423 var certRequested bool
424 certReq, ok := msg.(*certificateRequestMsg)
425 if ok {
426 certRequested = true
427 hs.finishedHash.Write(certReq.marshal())
428
429 if chainToSend, err = hs.getCertificate(certReq); err != nil {
430 c.sendAlert(alertInternalError)
431 return err
432 }
433
434 msg, err = c.readHandshake()
435 if err != nil {
436 return err
437 }
438 }
439
440 shd, ok := msg.(*serverHelloDoneMsg)
441 if !ok {
442 c.sendAlert(alertUnexpectedMessage)
443 return unexpectedMessageError(shd, msg)
444 }
445 hs.finishedHash.Write(shd.marshal())
446
447
448
449
450 if certRequested {
451 certMsg = new(certificateMsg)
452 certMsg.certificates = chainToSend.Certificate
453 hs.finishedHash.Write(certMsg.marshal())
454 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
455 return err
456 }
457 }
458
459 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
460 if err != nil {
461 c.sendAlert(alertInternalError)
462 return err
463 }
464 if ckx != nil {
465 hs.finishedHash.Write(ckx.marshal())
466 if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
467 return err
468 }
469 }
470
471 if chainToSend != nil && len(chainToSend.Certificate) > 0 {
472 certVerify := &certificateVerifyMsg{
473 hasSignatureAndHash: c.vers >= VersionTLS12,
474 }
475
476 key, ok := chainToSend.PrivateKey.(crypto.Signer)
477 if !ok {
478 c.sendAlert(alertInternalError)
479 return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
480 }
481
482 var signatureType uint8
483 switch key.Public().(type) {
484 case *ecdsa.PublicKey:
485 signatureType = signatureECDSA
486 case *rsa.PublicKey:
487 signatureType = signatureRSA
488 default:
489 c.sendAlert(alertInternalError)
490 return fmt.Errorf("tls: failed to sign handshake with client certificate: unknown client certificate key type: %T", key)
491 }
492
493
494 if certVerify.hasSignatureAndHash {
495 certVerify.signatureAlgorithm, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.supportedSignatureAlgorithms, signatureType)
496 if err != nil {
497 c.sendAlert(alertInternalError)
498 return err
499 }
500 }
501 digest, hashFunc, err := hs.finishedHash.hashForClientCertificate(signatureType, certVerify.signatureAlgorithm, hs.masterSecret)
502 if err != nil {
503 c.sendAlert(alertInternalError)
504 return err
505 }
506 certVerify.signature, err = key.Sign(c.config.rand(), digest, hashFunc)
507 if err != nil {
508 c.sendAlert(alertInternalError)
509 return err
510 }
511
512 hs.finishedHash.Write(certVerify.marshal())
513 if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
514 return err
515 }
516 }
517
518 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
519 if err := c.config.writeKeyLog(hs.hello.random, hs.masterSecret); err != nil {
520 c.sendAlert(alertInternalError)
521 return errors.New("tls: failed to write to key log: " + err.Error())
522 }
523
524 hs.finishedHash.discardHandshakeBuffer()
525
526 return nil
527 }
528
529 func (hs *clientHandshakeState) establishKeys() error {
530 c := hs.c
531
532 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
533 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
534 var clientCipher, serverCipher interface{}
535 var clientHash, serverHash macFunction
536 if hs.suite.cipher != nil {
537 clientCipher = hs.suite.cipher(clientKey, clientIV, false )
538 clientHash = hs.suite.mac(c.vers, clientMAC)
539 serverCipher = hs.suite.cipher(serverKey, serverIV, true )
540 serverHash = hs.suite.mac(c.vers, serverMAC)
541 } else {
542 clientCipher = hs.suite.aead(clientKey, clientIV)
543 serverCipher = hs.suite.aead(serverKey, serverIV)
544 }
545
546 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
547 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
548 return nil
549 }
550
551 func (hs *clientHandshakeState) serverResumedSession() bool {
552
553
554 return hs.session != nil && hs.hello.sessionId != nil &&
555 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
556 }
557
558 func (hs *clientHandshakeState) processServerHello() (bool, error) {
559 c := hs.c
560
561 if hs.serverHello.compressionMethod != compressionNone {
562 c.sendAlert(alertUnexpectedMessage)
563 return false, errors.New("tls: server selected unsupported compression format")
564 }
565
566 if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
567 c.secureRenegotiation = true
568 if len(hs.serverHello.secureRenegotiation) != 0 {
569 c.sendAlert(alertHandshakeFailure)
570 return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
571 }
572 }
573
574 if c.handshakes > 0 && c.secureRenegotiation {
575 var expectedSecureRenegotiation [24]byte
576 copy(expectedSecureRenegotiation[:], c.clientFinished[:])
577 copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
578 if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
579 c.sendAlert(alertHandshakeFailure)
580 return false, errors.New("tls: incorrect renegotiation extension contents")
581 }
582 }
583
584 clientDidNPN := hs.hello.nextProtoNeg
585 clientDidALPN := len(hs.hello.alpnProtocols) > 0
586 serverHasNPN := hs.serverHello.nextProtoNeg
587 serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
588
589 if !clientDidNPN && serverHasNPN {
590 c.sendAlert(alertHandshakeFailure)
591 return false, errors.New("tls: server advertised unrequested NPN extension")
592 }
593
594 if !clientDidALPN && serverHasALPN {
595 c.sendAlert(alertHandshakeFailure)
596 return false, errors.New("tls: server advertised unrequested ALPN extension")
597 }
598
599 if serverHasNPN && serverHasALPN {
600 c.sendAlert(alertHandshakeFailure)
601 return false, errors.New("tls: server advertised both NPN and ALPN extensions")
602 }
603
604 if serverHasALPN {
605 c.clientProtocol = hs.serverHello.alpnProtocol
606 c.clientProtocolFallback = false
607 }
608 c.scts = hs.serverHello.scts
609
610 if !hs.serverResumedSession() {
611 return false, nil
612 }
613
614 if hs.session.vers != c.vers {
615 c.sendAlert(alertHandshakeFailure)
616 return false, errors.New("tls: server resumed a session with a different version")
617 }
618
619 if hs.session.cipherSuite != hs.suite.id {
620 c.sendAlert(alertHandshakeFailure)
621 return false, errors.New("tls: server resumed a session with a different cipher suite")
622 }
623
624
625 hs.masterSecret = hs.session.masterSecret
626 c.peerCertificates = hs.session.serverCertificates
627 c.verifiedChains = hs.session.verifiedChains
628 return true, nil
629 }
630
631 func (hs *clientHandshakeState) readFinished(out []byte) error {
632 c := hs.c
633
634 c.readRecord(recordTypeChangeCipherSpec)
635 if c.in.err != nil {
636 return c.in.err
637 }
638
639 msg, err := c.readHandshake()
640 if err != nil {
641 return err
642 }
643 serverFinished, ok := msg.(*finishedMsg)
644 if !ok {
645 c.sendAlert(alertUnexpectedMessage)
646 return unexpectedMessageError(serverFinished, msg)
647 }
648
649 verify := hs.finishedHash.serverSum(hs.masterSecret)
650 if len(verify) != len(serverFinished.verifyData) ||
651 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
652 c.sendAlert(alertHandshakeFailure)
653 return errors.New("tls: server's Finished message was incorrect")
654 }
655 hs.finishedHash.Write(serverFinished.marshal())
656 copy(out, verify)
657 return nil
658 }
659
660 func (hs *clientHandshakeState) readSessionTicket() error {
661 if !hs.serverHello.ticketSupported {
662 return nil
663 }
664
665 c := hs.c
666 msg, err := c.readHandshake()
667 if err != nil {
668 return err
669 }
670 sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
671 if !ok {
672 c.sendAlert(alertUnexpectedMessage)
673 return unexpectedMessageError(sessionTicketMsg, msg)
674 }
675 hs.finishedHash.Write(sessionTicketMsg.marshal())
676
677 hs.session = &ClientSessionState{
678 sessionTicket: sessionTicketMsg.ticket,
679 vers: c.vers,
680 cipherSuite: hs.suite.id,
681 masterSecret: hs.masterSecret,
682 serverCertificates: c.peerCertificates,
683 verifiedChains: c.verifiedChains,
684 }
685
686 return nil
687 }
688
689 func (hs *clientHandshakeState) sendFinished(out []byte) error {
690 c := hs.c
691
692 if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
693 return err
694 }
695 if hs.serverHello.nextProtoNeg {
696 nextProto := new(nextProtoMsg)
697 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
698 nextProto.proto = proto
699 c.clientProtocol = proto
700 c.clientProtocolFallback = fallback
701
702 hs.finishedHash.Write(nextProto.marshal())
703 if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil {
704 return err
705 }
706 }
707
708 finished := new(finishedMsg)
709 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
710 hs.finishedHash.Write(finished.marshal())
711 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
712 return err
713 }
714 copy(out, finished.verifyData)
715 return nil
716 }
717
718
719
720 var tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}
721
722 const (
723
724
725 tls11SignatureSchemesNumECDSA = 3
726
727
728 tls11SignatureSchemesNumRSA = 4
729 )
730
731 func (hs *clientHandshakeState) getCertificate(certReq *certificateRequestMsg) (*Certificate, error) {
732 c := hs.c
733
734 var rsaAvail, ecdsaAvail bool
735 for _, certType := range certReq.certificateTypes {
736 switch certType {
737 case certTypeRSASign:
738 rsaAvail = true
739 case certTypeECDSASign:
740 ecdsaAvail = true
741 }
742 }
743
744 if c.config.GetClientCertificate != nil {
745 var signatureSchemes []SignatureScheme
746
747 if !certReq.hasSignatureAndHash {
748
749
750
751
752 signatureSchemes = tls11SignatureSchemes
753 if !ecdsaAvail {
754 signatureSchemes = signatureSchemes[tls11SignatureSchemesNumECDSA:]
755 }
756 if !rsaAvail {
757 signatureSchemes = signatureSchemes[:len(signatureSchemes)-tls11SignatureSchemesNumRSA]
758 }
759 } else {
760 signatureSchemes = certReq.supportedSignatureAlgorithms
761 }
762
763 return c.config.GetClientCertificate(&CertificateRequestInfo{
764 AcceptableCAs: certReq.certificateAuthorities,
765 SignatureSchemes: signatureSchemes,
766 })
767 }
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783 findCert:
784 for i, chain := range c.config.Certificates {
785 if !rsaAvail && !ecdsaAvail {
786 continue
787 }
788
789 for j, cert := range chain.Certificate {
790 x509Cert := chain.Leaf
791
792
793 if j != 0 || x509Cert == nil {
794 var err error
795 if x509Cert, err = x509.ParseCertificate(cert); err != nil {
796 c.sendAlert(alertInternalError)
797 return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
798 }
799 }
800
801 switch {
802 case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
803 case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
804 default:
805 continue findCert
806 }
807
808 if len(certReq.certificateAuthorities) == 0 {
809
810
811 return &chain, nil
812 }
813
814 for _, ca := range certReq.certificateAuthorities {
815 if bytes.Equal(x509Cert.RawIssuer, ca) {
816 return &chain, nil
817 }
818 }
819 }
820 }
821
822
823 return new(Certificate), nil
824 }
825
826
827
828 func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
829 if len(config.ServerName) > 0 {
830 return config.ServerName
831 }
832 return serverAddr.String()
833 }
834
835
836
837
838
839 func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
840 for _, s := range preferenceProtos {
841 for _, c := range protos {
842 if s == c {
843 return s, false
844 }
845 }
846 }
847
848 return protos[0], true
849 }
850
851
852
853
854 func hostnameInSNI(name string) string {
855 host := name
856 if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
857 host = host[1 : len(host)-1]
858 }
859 if i := strings.LastIndex(host, "%"); i > 0 {
860 host = host[:i]
861 }
862 if net.ParseIP(host) != nil {
863 return ""
864 }
865 for len(name) > 0 && name[len(name)-1] == '.' {
866 name = name[:len(name)-1]
867 }
868 return name
869 }
870
View as plain text