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.
22 // serverHandshakeState contains details of a server handshake in progress.
23 // It's discarded once the handshake has completed.
24 type serverHandshakeState struct {
26 clientHello *clientHelloMsg
33 sessionState *sessionState
34 finishedHash finishedHash
39 // serverHandshake performs a TLS handshake as a server.
40 func (c *Conn) serverHandshake() error {
41 clientHello, err := c.readClientHello()
46 if c.vers == VersionTLS13 {
47 hs := serverHandshakeStateTLS13{
49 clientHello: clientHello,
54 hs := serverHandshakeState{
56 clientHello: clientHello,
61 func (hs *serverHandshakeState) handshake() error {
64 if err := hs.processClientHello(); err != nil {
68 // For an overview of TLS handshaking, see RFC 5246, Section 7.3.
70 if hs.checkForResumption() {
71 // The client has included a session ticket and so we do an abbreviated handshake.
73 if err := hs.doResumeHandshake(); err != nil {
76 if err := hs.establishKeys(); err != nil {
79 if err := hs.sendSessionTicket(); err != nil {
82 if err := hs.sendFinished(c.serverFinished[:]); err != nil {
85 if _, err := c.flush(); err != nil {
88 c.clientFinishedIsFirst = false
89 if err := hs.readFinished(nil); err != nil {
93 // The client didn't include a session ticket, or it wasn't
94 // valid so we do a full handshake.
95 if err := hs.pickCipherSuite(); err != nil {
98 if err := hs.doFullHandshake(); err != nil {
101 if err := hs.establishKeys(); err != nil {
104 if err := hs.readFinished(c.clientFinished[:]); err != nil {
107 c.clientFinishedIsFirst = true
109 if err := hs.sendSessionTicket(); err != nil {
112 if err := hs.sendFinished(nil); err != nil {
115 if _, err := c.flush(); err != nil {
120 c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
121 atomic.StoreUint32(&c.handshakeStatus, 1)
126 // readClientHello reads a ClientHello message and selects the protocol version.
127 func (c *Conn) readClientHello() (*clientHelloMsg, error) {
128 msg, err := c.readHandshake()
132 clientHello, ok := msg.(*clientHelloMsg)
134 c.sendAlert(alertUnexpectedMessage)
135 return nil, unexpectedMessageError(clientHello, msg)
138 var configForClient *Config
139 originalConfig := c.config
140 if c.config.GetConfigForClient != nil {
141 chi := clientHelloInfo(c, clientHello)
142 if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
143 c.sendAlert(alertInternalError)
145 } else if configForClient != nil {
146 c.config = configForClient
149 c.ticketKeys = originalConfig.ticketKeys(configForClient)
151 clientVersions := clientHello.supportedVersions
152 if len(clientHello.supportedVersions) == 0 {
153 clientVersions = supportedVersionsFromMax(clientHello.vers)
155 c.vers, ok = c.config.mutualVersion(clientVersions)
157 c.sendAlert(alertProtocolVersion)
158 return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
161 c.in.version = c.vers
162 c.out.version = c.vers
164 return clientHello, nil
167 func (hs *serverHandshakeState) processClientHello() error {
170 hs.hello = new(serverHelloMsg)
171 hs.hello.vers = c.vers
173 foundCompression := false
174 // We only support null compression, so check that the client offered it.
175 for _, compression := range hs.clientHello.compressionMethods {
176 if compression == compressionNone {
177 foundCompression = true
182 if !foundCompression {
183 c.sendAlert(alertHandshakeFailure)
184 return errors.New("tls: client does not support uncompressed connections")
187 hs.hello.random = make([]byte, 32)
188 serverRandom := hs.hello.random
189 // Downgrade protection canaries. See RFC 8446, Section 4.1.3.
190 maxVers := c.config.maxSupportedVersion()
191 if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
192 if c.vers == VersionTLS12 {
193 copy(serverRandom[24:], downgradeCanaryTLS12)
195 copy(serverRandom[24:], downgradeCanaryTLS11)
197 serverRandom = serverRandom[:24]
199 _, err := io.ReadFull(c.config.rand(), serverRandom)
201 c.sendAlert(alertInternalError)
205 if len(hs.clientHello.secureRenegotiation) != 0 {
206 c.sendAlert(alertHandshakeFailure)
207 return errors.New("tls: initial handshake had non-empty renegotiation extension")
210 hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
211 hs.hello.compressionMethod = compressionNone
212 if len(hs.clientHello.serverName) > 0 {
213 c.serverName = hs.clientHello.serverName
216 if len(hs.clientHello.alpnProtocols) > 0 {
217 if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" {
218 hs.hello.alpnProtocol = selectedProto
219 c.clientProtocol = selectedProto
223 hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
225 if err == errNoCertificates {
226 c.sendAlert(alertUnrecognizedName)
228 c.sendAlert(alertInternalError)
232 if hs.clientHello.scts {
233 hs.hello.scts = hs.cert.SignedCertificateTimestamps
236 hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
239 // Although omitting the ec_point_formats extension is permitted, some
240 // old OpenSSL version will refuse to handshake if not present.
242 // Per RFC 4492, section 5.1.2, implementations MUST support the
243 // uncompressed point format. See golang.org/issue/31943.
244 hs.hello.supportedPoints = []uint8{pointFormatUncompressed}
247 if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
248 switch priv.Public().(type) {
249 case *ecdsa.PublicKey:
251 case ed25519.PublicKey:
256 c.sendAlert(alertInternalError)
257 return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
260 if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
261 switch priv.Public().(type) {
263 hs.rsaDecryptOk = true
265 c.sendAlert(alertInternalError)
266 return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
273 // supportsECDHE returns whether ECDHE key exchanges can be used with this
274 // pre-TLS 1.3 client.
275 func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
276 supportsCurve := false
277 for _, curve := range supportedCurves {
278 if c.supportsCurve(curve) {
284 supportsPointFormat := false
285 for _, pointFormat := range supportedPoints {
286 if pointFormat == pointFormatUncompressed {
287 supportsPointFormat = true
292 return supportsCurve && supportsPointFormat
295 func (hs *serverHandshakeState) pickCipherSuite() error {
298 var preferenceList, supportedList []uint16
299 if c.config.PreferServerCipherSuites {
300 preferenceList = c.config.cipherSuites()
301 supportedList = hs.clientHello.cipherSuites
303 // If the client does not seem to have hardware support for AES-GCM,
304 // and the application did not specify a cipher suite preference order,
305 // prefer other AEAD ciphers even if we prioritized AES-GCM ciphers
307 if c.config.CipherSuites == nil && !aesgcmPreferred(hs.clientHello.cipherSuites) {
308 preferenceList = deprioritizeAES(preferenceList)
311 preferenceList = hs.clientHello.cipherSuites
312 supportedList = c.config.cipherSuites()
314 // If we don't have hardware support for AES-GCM, prefer other AEAD
315 // ciphers even if the client prioritized AES-GCM.
316 // If BoringCrypto is enabled, always prioritize AES-GCM.
317 if !hasAESGCMHardwareSupport && !boringEnabled {
318 preferenceList = deprioritizeAES(preferenceList)
322 hs.suite = selectCipherSuite(preferenceList, supportedList, hs.cipherSuiteOk)
324 c.sendAlert(alertHandshakeFailure)
325 return errors.New("tls: no cipher suite supported by both client and server")
327 c.cipherSuite = hs.suite.id
329 for _, id := range hs.clientHello.cipherSuites {
330 if id == TLS_FALLBACK_SCSV {
331 // The client is doing a fallback connection. See RFC 7507.
332 if hs.clientHello.vers < c.config.maxSupportedVersion() {
333 c.sendAlert(alertInappropriateFallback)
334 return errors.New("tls: client using inappropriate protocol fallback")
343 func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
344 if c.flags&suiteECDHE != 0 {
348 if c.flags&suiteECSign != 0 {
352 } else if !hs.rsaSignOk {
355 } else if !hs.rsaDecryptOk {
358 if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
364 // checkForResumption reports whether we should perform resumption on this connection.
365 func (hs *serverHandshakeState) checkForResumption() bool {
368 if c.config.SessionTicketsDisabled {
372 plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket)
373 if plaintext == nil {
376 hs.sessionState = &sessionState{usedOldKey: usedOldKey}
377 ok := hs.sessionState.unmarshal(plaintext)
382 createdAt := time.Unix(int64(hs.sessionState.createdAt), 0)
383 if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
387 // Never resume a session for a different TLS version.
388 if c.vers != hs.sessionState.vers {
392 cipherSuiteOk := false
393 // Check that the client is still offering the ciphersuite in the session.
394 for _, id := range hs.clientHello.cipherSuites {
395 if id == hs.sessionState.cipherSuite {
404 // Check that we also support the ciphersuite from the session.
405 hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite},
406 c.config.cipherSuites(), hs.cipherSuiteOk)
411 sessionHasClientCerts := len(hs.sessionState.certificates) != 0
412 needClientCerts := requiresClientCert(c.config.ClientAuth)
413 if needClientCerts && !sessionHasClientCerts {
416 if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
423 func (hs *serverHandshakeState) doResumeHandshake() error {
426 hs.hello.cipherSuite = hs.suite.id
427 c.cipherSuite = hs.suite.id
428 // We echo the client's session ID in the ServerHello to let it know
429 // that we're doing a resumption.
430 hs.hello.sessionId = hs.clientHello.sessionId
431 hs.hello.ticketSupported = hs.sessionState.usedOldKey
432 hs.finishedHash = newFinishedHash(c.vers, hs.suite)
433 hs.finishedHash.discardHandshakeBuffer()
434 hs.finishedHash.Write(hs.clientHello.marshal())
435 hs.finishedHash.Write(hs.hello.marshal())
436 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
440 if err := c.processCertsFromClient(Certificate{
441 Certificate: hs.sessionState.certificates,
446 if c.config.VerifyConnection != nil {
447 if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
448 c.sendAlert(alertBadCertificate)
453 hs.masterSecret = hs.sessionState.masterSecret
458 func (hs *serverHandshakeState) doFullHandshake() error {
461 if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
462 hs.hello.ocspStapling = true
465 hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
466 hs.hello.cipherSuite = hs.suite.id
468 hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
469 if c.config.ClientAuth == NoClientCert {
470 // No need to keep a full record of the handshake if client
471 // certificates won't be used.
472 hs.finishedHash.discardHandshakeBuffer()
474 hs.finishedHash.Write(hs.clientHello.marshal())
475 hs.finishedHash.Write(hs.hello.marshal())
476 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
480 certMsg := new(certificateMsg)
481 certMsg.certificates = hs.cert.Certificate
482 hs.finishedHash.Write(certMsg.marshal())
483 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
487 if hs.hello.ocspStapling {
488 certStatus := new(certificateStatusMsg)
489 certStatus.response = hs.cert.OCSPStaple
490 hs.finishedHash.Write(certStatus.marshal())
491 if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
496 keyAgreement := hs.suite.ka(c.vers)
497 skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
499 c.sendAlert(alertHandshakeFailure)
503 hs.finishedHash.Write(skx.marshal())
504 if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
509 var certReq *certificateRequestMsg
510 if c.config.ClientAuth >= RequestClientCert {
511 // Request a client certificate
512 certReq = new(certificateRequestMsg)
513 certReq.certificateTypes = []byte{
514 byte(certTypeRSASign),
515 byte(certTypeECDSASign),
517 if c.vers >= VersionTLS12 {
518 certReq.hasSignatureAlgorithm = true
519 certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
522 // An empty list of certificateAuthorities signals to
523 // the client that it may send any certificate in response
524 // to our request. When we know the CAs we trust, then
525 // we can send them down, so that the client can choose
526 // an appropriate certificate to give to us.
527 if c.config.ClientCAs != nil {
528 certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
530 hs.finishedHash.Write(certReq.marshal())
531 if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
536 helloDone := new(serverHelloDoneMsg)
537 hs.finishedHash.Write(helloDone.marshal())
538 if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
542 if _, err := c.flush(); err != nil {
546 var pub crypto.PublicKey // public key for client auth, if any
548 msg, err := c.readHandshake()
553 // If we requested a client certificate, then the client must send a
554 // certificate message, even if it's empty.
555 if c.config.ClientAuth >= RequestClientCert {
556 certMsg, ok := msg.(*certificateMsg)
558 c.sendAlert(alertUnexpectedMessage)
559 return unexpectedMessageError(certMsg, msg)
561 hs.finishedHash.Write(certMsg.marshal())
563 if err := c.processCertsFromClient(Certificate{
564 Certificate: certMsg.certificates,
568 if len(certMsg.certificates) != 0 {
569 pub = c.peerCertificates[0].PublicKey
572 msg, err = c.readHandshake()
577 if c.config.VerifyConnection != nil {
578 if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
579 c.sendAlert(alertBadCertificate)
584 // Get client key exchange
585 ckx, ok := msg.(*clientKeyExchangeMsg)
587 c.sendAlert(alertUnexpectedMessage)
588 return unexpectedMessageError(ckx, msg)
590 hs.finishedHash.Write(ckx.marshal())
592 preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
594 c.sendAlert(alertHandshakeFailure)
597 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
598 if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
599 c.sendAlert(alertInternalError)
603 // If we received a client cert in response to our certificate request message,
604 // the client will send us a certificateVerifyMsg immediately after the
605 // clientKeyExchangeMsg. This message is a digest of all preceding
606 // handshake-layer messages that is signed using the private key corresponding
607 // to the client's certificate. This allows us to verify that the client is in
608 // possession of the private key of the certificate.
609 if len(c.peerCertificates) > 0 {
610 msg, err = c.readHandshake()
614 certVerify, ok := msg.(*certificateVerifyMsg)
616 c.sendAlert(alertUnexpectedMessage)
617 return unexpectedMessageError(certVerify, msg)
621 var sigHash crypto.Hash
622 if c.vers >= VersionTLS12 {
623 if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
624 c.sendAlert(alertIllegalParameter)
625 return errors.New("tls: client certificate used with invalid signature algorithm")
627 sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
629 return c.sendAlert(alertInternalError)
632 sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
634 c.sendAlert(alertIllegalParameter)
639 signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
640 if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
641 c.sendAlert(alertDecryptError)
642 return errors.New("tls: invalid signature by the client certificate: " + err.Error())
645 hs.finishedHash.Write(certVerify.marshal())
648 hs.finishedHash.discardHandshakeBuffer()
653 func (hs *serverHandshakeState) establishKeys() error {
656 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
657 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
659 var clientCipher, serverCipher interface{}
660 var clientHash, serverHash hash.Hash
662 if hs.suite.aead == nil {
663 clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
664 clientHash = hs.suite.mac(clientMAC)
665 serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
666 serverHash = hs.suite.mac(serverMAC)
668 clientCipher = hs.suite.aead(clientKey, clientIV)
669 serverCipher = hs.suite.aead(serverKey, serverIV)
672 c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
673 c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
678 func (hs *serverHandshakeState) readFinished(out []byte) error {
681 if err := c.readChangeCipherSpec(); err != nil {
685 msg, err := c.readHandshake()
689 clientFinished, ok := msg.(*finishedMsg)
691 c.sendAlert(alertUnexpectedMessage)
692 return unexpectedMessageError(clientFinished, msg)
695 verify := hs.finishedHash.clientSum(hs.masterSecret)
696 if len(verify) != len(clientFinished.verifyData) ||
697 subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
698 c.sendAlert(alertHandshakeFailure)
699 return errors.New("tls: client's Finished message is incorrect")
702 hs.finishedHash.Write(clientFinished.marshal())
707 func (hs *serverHandshakeState) sendSessionTicket() error {
708 // ticketSupported is set in a resumption handshake if the
709 // ticket from the client was encrypted with an old session
710 // ticket key and thus a refreshed ticket should be sent.
711 if !hs.hello.ticketSupported {
716 m := new(newSessionTicketMsg)
718 createdAt := uint64(c.config.time().Unix())
719 if hs.sessionState != nil {
720 // If this is re-wrapping an old key, then keep
721 // the original time it was created.
722 createdAt = hs.sessionState.createdAt
725 var certsFromClient [][]byte
726 for _, cert := range c.peerCertificates {
727 certsFromClient = append(certsFromClient, cert.Raw)
729 state := sessionState{
731 cipherSuite: hs.suite.id,
732 createdAt: createdAt,
733 masterSecret: hs.masterSecret,
734 certificates: certsFromClient,
737 m.ticket, err = c.encryptTicket(state.marshal())
742 hs.finishedHash.Write(m.marshal())
743 if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
750 func (hs *serverHandshakeState) sendFinished(out []byte) error {
753 if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
757 finished := new(finishedMsg)
758 finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
759 hs.finishedHash.Write(finished.marshal())
760 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
764 copy(out, finished.verifyData)
769 // processCertsFromClient takes a chain of client certificates either from a
770 // Certificates message or from a sessionState and verifies them. It returns
771 // the public key of the leaf certificate.
772 func (c *Conn) processCertsFromClient(certificate Certificate) error {
773 certificates := certificate.Certificate
774 certs := make([]*x509.Certificate, len(certificates))
776 for i, asn1Data := range certificates {
777 if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
778 c.sendAlert(alertBadCertificate)
779 return errors.New("tls: failed to parse client certificate: " + err.Error())
783 if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
784 c.sendAlert(alertBadCertificate)
785 return errors.New("tls: client didn't provide a certificate")
788 if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
789 opts := x509.VerifyOptions{
790 IsBoring: isBoringCertificate,
792 Roots: c.config.ClientCAs,
793 CurrentTime: c.config.time(),
794 Intermediates: x509.NewCertPool(),
795 KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
798 for _, cert := range certs[1:] {
799 opts.Intermediates.AddCert(cert)
802 chains, err := certs[0].Verify(opts)
804 c.sendAlert(alertBadCertificate)
805 return errors.New("tls: failed to verify client certificate: " + err.Error())
808 c.verifiedChains = chains
811 c.peerCertificates = certs
812 c.ocspResponse = certificate.OCSPStaple
813 c.scts = certificate.SignedCertificateTimestamps
816 switch certs[0].PublicKey.(type) {
817 case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
819 c.sendAlert(alertUnsupportedCertificate)
820 return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
824 if c.config.VerifyPeerCertificate != nil {
825 if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
826 c.sendAlert(alertBadCertificate)
834 func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
835 supportedVersions := clientHello.supportedVersions
836 if len(clientHello.supportedVersions) == 0 {
837 supportedVersions = supportedVersionsFromMax(clientHello.vers)
840 return &ClientHelloInfo{
841 CipherSuites: clientHello.cipherSuites,
842 ServerName: clientHello.serverName,
843 SupportedCurves: clientHello.supportedCurves,
844 SupportedPoints: clientHello.supportedPoints,
845 SignatureSchemes: clientHello.supportedSignatureAlgorithms,
846 SupportedProtos: clientHello.alpnProtocols,
847 SupportedVersions: supportedVersions,