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