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