1 // Copyright 2018 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.
18 type clientHandshakeStateTLS13 struct {
20 serverHello *serverHelloMsg
22 ecdheParams ecdheParameters
24 session *ClientSessionState
28 certReq *certificateRequestMsgTLS13
31 suite *cipherSuiteTLS13
34 trafficSecret []byte // client_application_traffic_secret_0
37 // handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and,
38 // optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
39 func (hs *clientHandshakeStateTLS13) handshake() error {
43 return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
46 // The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
47 // sections 4.1.2 and 4.1.3.
49 c.sendAlert(alertProtocolVersion)
50 return errors.New("tls: server selected TLS 1.3 in a renegotiation")
53 // Consistency check on the presence of a keyShare and its parameters.
54 if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 {
55 return c.sendAlert(alertInternalError)
58 if err := hs.checkServerHelloOrHRR(); err != nil {
62 hs.transcript = hs.suite.hash.New()
63 hs.transcript.Write(hs.hello.marshal())
65 if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
66 if err := hs.sendDummyChangeCipherSpec(); err != nil {
69 if err := hs.processHelloRetryRequest(); err != nil {
74 hs.transcript.Write(hs.serverHello.marshal())
77 if err := hs.processServerHello(); err != nil {
80 if err := hs.sendDummyChangeCipherSpec(); err != nil {
83 if err := hs.establishHandshakeKeys(); err != nil {
86 if err := hs.readServerParameters(); err != nil {
89 if err := hs.readServerCertificate(); err != nil {
92 if err := hs.readServerFinished(); err != nil {
95 if err := hs.sendClientCertificate(); err != nil {
98 if err := hs.sendClientFinished(); err != nil {
101 if _, err := c.flush(); err != nil {
105 atomic.StoreUint32(&c.handshakeStatus, 1)
110 // checkServerHelloOrHRR does validity checks that apply to both ServerHello and
111 // HelloRetryRequest messages. It sets hs.suite.
112 func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
115 if hs.serverHello.supportedVersion == 0 {
116 c.sendAlert(alertMissingExtension)
117 return errors.New("tls: server selected TLS 1.3 using the legacy version field")
120 if hs.serverHello.supportedVersion != VersionTLS13 {
121 c.sendAlert(alertIllegalParameter)
122 return errors.New("tls: server selected an invalid version after a HelloRetryRequest")
125 if hs.serverHello.vers != VersionTLS12 {
126 c.sendAlert(alertIllegalParameter)
127 return errors.New("tls: server sent an incorrect legacy version")
130 if hs.serverHello.ocspStapling ||
131 hs.serverHello.ticketSupported ||
132 hs.serverHello.secureRenegotiationSupported ||
133 len(hs.serverHello.secureRenegotiation) != 0 ||
134 len(hs.serverHello.alpnProtocol) != 0 ||
135 len(hs.serverHello.scts) != 0 {
136 c.sendAlert(alertUnsupportedExtension)
137 return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3")
140 if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
141 c.sendAlert(alertIllegalParameter)
142 return errors.New("tls: server did not echo the legacy session ID")
145 if hs.serverHello.compressionMethod != compressionNone {
146 c.sendAlert(alertIllegalParameter)
147 return errors.New("tls: server selected unsupported compression format")
150 selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
151 if hs.suite != nil && selectedSuite != hs.suite {
152 c.sendAlert(alertIllegalParameter)
153 return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
155 if selectedSuite == nil {
156 c.sendAlert(alertIllegalParameter)
157 return errors.New("tls: server chose an unconfigured cipher suite")
159 hs.suite = selectedSuite
160 c.cipherSuite = hs.suite.id
165 // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
166 // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
167 func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
171 hs.sentDummyCCS = true
173 _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
177 // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
178 // resends hs.hello, and reads the new ServerHello into hs.serverHello.
179 func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
182 // The first ClientHello gets double-hashed into the transcript upon a
183 // HelloRetryRequest. (The idea is that the server might offload transcript
184 // storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
185 chHash := hs.transcript.Sum(nil)
186 hs.transcript.Reset()
187 hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
188 hs.transcript.Write(chHash)
189 hs.transcript.Write(hs.serverHello.marshal())
191 // The only HelloRetryRequest extensions we support are key_share and
192 // cookie, and clients must abort the handshake if the HRR would not result
193 // in any change in the ClientHello.
194 if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
195 c.sendAlert(alertIllegalParameter)
196 return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
199 if hs.serverHello.cookie != nil {
200 hs.hello.cookie = hs.serverHello.cookie
203 if hs.serverHello.serverShare.group != 0 {
204 c.sendAlert(alertDecodeError)
205 return errors.New("tls: received malformed key_share extension")
208 // If the server sent a key_share extension selecting a group, ensure it's
209 // a group we advertised but did not send a key share for, and send a key
210 // share for it this time.
211 if curveID := hs.serverHello.selectedGroup; curveID != 0 {
213 for _, id := range hs.hello.supportedCurves {
220 c.sendAlert(alertIllegalParameter)
221 return errors.New("tls: server selected unsupported group")
223 if hs.ecdheParams.CurveID() == curveID {
224 c.sendAlert(alertIllegalParameter)
225 return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
227 if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
228 c.sendAlert(alertInternalError)
229 return errors.New("tls: CurvePreferences includes unsupported curve")
231 params, err := generateECDHEParameters(c.config.rand(), curveID)
233 c.sendAlert(alertInternalError)
236 hs.ecdheParams = params
237 hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
241 if len(hs.hello.pskIdentities) > 0 {
242 pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
244 return c.sendAlert(alertInternalError)
246 if pskSuite.hash == hs.suite.hash {
247 // Update binders and obfuscated_ticket_age.
248 ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond)
249 hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd
251 transcript := hs.suite.hash.New()
252 transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
253 transcript.Write(chHash)
254 transcript.Write(hs.serverHello.marshal())
255 transcript.Write(hs.hello.marshalWithoutBinders())
256 pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
257 hs.hello.updateBinders(pskBinders)
259 // Server selected a cipher suite incompatible with the PSK.
260 hs.hello.pskIdentities = nil
261 hs.hello.pskBinders = nil
265 hs.transcript.Write(hs.hello.marshal())
266 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
270 msg, err := c.readHandshake()
275 serverHello, ok := msg.(*serverHelloMsg)
277 c.sendAlert(alertUnexpectedMessage)
278 return unexpectedMessageError(serverHello, msg)
280 hs.serverHello = serverHello
282 if err := hs.checkServerHelloOrHRR(); err != nil {
289 func (hs *clientHandshakeStateTLS13) processServerHello() error {
292 if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
293 c.sendAlert(alertUnexpectedMessage)
294 return errors.New("tls: server sent two HelloRetryRequest messages")
297 if len(hs.serverHello.cookie) != 0 {
298 c.sendAlert(alertUnsupportedExtension)
299 return errors.New("tls: server sent a cookie in a normal ServerHello")
302 if hs.serverHello.selectedGroup != 0 {
303 c.sendAlert(alertDecodeError)
304 return errors.New("tls: malformed key_share extension")
307 if hs.serverHello.serverShare.group == 0 {
308 c.sendAlert(alertIllegalParameter)
309 return errors.New("tls: server did not send a key share")
311 if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
312 c.sendAlert(alertIllegalParameter)
313 return errors.New("tls: server selected unsupported group")
316 if !hs.serverHello.selectedIdentityPresent {
320 if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
321 c.sendAlert(alertIllegalParameter)
322 return errors.New("tls: server selected an invalid PSK")
325 if len(hs.hello.pskIdentities) != 1 || hs.session == nil {
326 return c.sendAlert(alertInternalError)
328 pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
330 return c.sendAlert(alertInternalError)
332 if pskSuite.hash != hs.suite.hash {
333 c.sendAlert(alertIllegalParameter)
334 return errors.New("tls: server selected an invalid PSK and cipher suite pair")
339 c.peerCertificates = hs.session.serverCertificates
340 c.verifiedChains = hs.session.verifiedChains
341 c.ocspResponse = hs.session.ocspResponse
342 c.scts = hs.session.scts
346 func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
349 sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
350 if sharedKey == nil {
351 c.sendAlert(alertIllegalParameter)
352 return errors.New("tls: invalid server key share")
355 earlySecret := hs.earlySecret
357 earlySecret = hs.suite.extract(nil, nil)
359 handshakeSecret := hs.suite.extract(sharedKey,
360 hs.suite.deriveSecret(earlySecret, "derived", nil))
362 clientSecret := hs.suite.deriveSecret(handshakeSecret,
363 clientHandshakeTrafficLabel, hs.transcript)
364 c.out.setTrafficSecret(hs.suite, clientSecret)
365 serverSecret := hs.suite.deriveSecret(handshakeSecret,
366 serverHandshakeTrafficLabel, hs.transcript)
367 c.in.setTrafficSecret(hs.suite, serverSecret)
369 err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
371 c.sendAlert(alertInternalError)
374 err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
376 c.sendAlert(alertInternalError)
380 hs.masterSecret = hs.suite.extract(nil,
381 hs.suite.deriveSecret(handshakeSecret, "derived", nil))
386 func (hs *clientHandshakeStateTLS13) readServerParameters() error {
389 msg, err := c.readHandshake()
394 encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
396 c.sendAlert(alertUnexpectedMessage)
397 return unexpectedMessageError(encryptedExtensions, msg)
399 hs.transcript.Write(encryptedExtensions.marshal())
401 if len(encryptedExtensions.alpnProtocol) != 0 && len(hs.hello.alpnProtocols) == 0 {
402 c.sendAlert(alertUnsupportedExtension)
403 return errors.New("tls: server advertised unrequested ALPN extension")
405 c.clientProtocol = encryptedExtensions.alpnProtocol
410 func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
413 // Either a PSK or a certificate is always used, but not both.
414 // See RFC 8446, Section 4.1.1.
416 // Make sure the connection is still being verified whether or not this
417 // is a resumption. Resumptions currently don't reverify certificates so
418 // they don't call verifyServerCertificate. See Issue 31641.
419 if c.config.VerifyConnection != nil {
420 if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
421 c.sendAlert(alertBadCertificate)
428 msg, err := c.readHandshake()
433 certReq, ok := msg.(*certificateRequestMsgTLS13)
435 hs.transcript.Write(certReq.marshal())
439 msg, err = c.readHandshake()
445 certMsg, ok := msg.(*certificateMsgTLS13)
447 c.sendAlert(alertUnexpectedMessage)
448 return unexpectedMessageError(certMsg, msg)
450 if len(certMsg.certificate.Certificate) == 0 {
451 c.sendAlert(alertDecodeError)
452 return errors.New("tls: received empty certificates message")
454 hs.transcript.Write(certMsg.marshal())
456 c.scts = certMsg.certificate.SignedCertificateTimestamps
457 c.ocspResponse = certMsg.certificate.OCSPStaple
459 if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
463 msg, err = c.readHandshake()
468 certVerify, ok := msg.(*certificateVerifyMsg)
470 c.sendAlert(alertUnexpectedMessage)
471 return unexpectedMessageError(certVerify, msg)
474 // See RFC 8446, Section 4.4.3.
475 if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
476 c.sendAlert(alertIllegalParameter)
477 return errors.New("tls: certificate used with invalid signature algorithm")
479 sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
481 return c.sendAlert(alertInternalError)
483 if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
484 c.sendAlert(alertIllegalParameter)
485 return errors.New("tls: certificate used with invalid signature algorithm")
487 signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
488 if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
489 sigHash, signed, certVerify.signature); err != nil {
490 c.sendAlert(alertDecryptError)
491 return errors.New("tls: invalid signature by the server certificate: " + err.Error())
494 hs.transcript.Write(certVerify.marshal())
499 func (hs *clientHandshakeStateTLS13) readServerFinished() error {
502 msg, err := c.readHandshake()
507 finished, ok := msg.(*finishedMsg)
509 c.sendAlert(alertUnexpectedMessage)
510 return unexpectedMessageError(finished, msg)
513 expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
514 if !hmac.Equal(expectedMAC, finished.verifyData) {
515 c.sendAlert(alertDecryptError)
516 return errors.New("tls: invalid server finished hash")
519 hs.transcript.Write(finished.marshal())
521 // Derive secrets that take context through the server Finished.
523 hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
524 clientApplicationTrafficLabel, hs.transcript)
525 serverSecret := hs.suite.deriveSecret(hs.masterSecret,
526 serverApplicationTrafficLabel, hs.transcript)
527 c.in.setTrafficSecret(hs.suite, serverSecret)
529 err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
531 c.sendAlert(alertInternalError)
534 err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
536 c.sendAlert(alertInternalError)
540 c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
545 func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
548 if hs.certReq == nil {
552 cert, err := c.getClientCertificate(&CertificateRequestInfo{
553 AcceptableCAs: hs.certReq.certificateAuthorities,
554 SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
561 certMsg := new(certificateMsgTLS13)
563 certMsg.certificate = *cert
564 certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
565 certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
567 hs.transcript.Write(certMsg.marshal())
568 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
572 // If we sent an empty certificate message, skip the CertificateVerify.
573 if len(cert.Certificate) == 0 {
577 certVerifyMsg := new(certificateVerifyMsg)
578 certVerifyMsg.hasSignatureAlgorithm = true
580 certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms)
582 // getClientCertificate returned a certificate incompatible with the
583 // CertificateRequestInfo supported signature algorithms.
584 c.sendAlert(alertHandshakeFailure)
588 sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
590 return c.sendAlert(alertInternalError)
593 signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
594 signOpts := crypto.SignerOpts(sigHash)
595 if sigType == signatureRSAPSS {
596 signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
598 sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
600 c.sendAlert(alertInternalError)
601 return errors.New("tls: failed to sign handshake: " + err.Error())
603 certVerifyMsg.signature = sig
605 hs.transcript.Write(certVerifyMsg.marshal())
606 if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil {
613 func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
616 finished := &finishedMsg{
617 verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
620 hs.transcript.Write(finished.marshal())
621 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
625 c.out.setTrafficSecret(hs.suite, hs.trafficSecret)
627 if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
628 c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
629 resumptionLabel, hs.transcript)
635 func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
637 c.sendAlert(alertUnexpectedMessage)
638 return errors.New("tls: received new session ticket from a client")
641 if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
645 // See RFC 8446, Section 4.6.1.
646 if msg.lifetime == 0 {
649 lifetime := time.Duration(msg.lifetime) * time.Second
650 if lifetime > maxSessionTicketLifetime {
651 c.sendAlert(alertIllegalParameter)
652 return errors.New("tls: received a session ticket with invalid lifetime")
655 cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
656 if cipherSuite == nil || c.resumptionSecret == nil {
657 return c.sendAlert(alertInternalError)
660 // Save the resumption_master_secret and nonce instead of deriving the PSK
661 // to do the least amount of work on NewSessionTicket messages before we
662 // know if the ticket will be used. Forward secrecy of resumed connections
663 // is guaranteed by the requirement for pskModeDHE.
664 session := &ClientSessionState{
665 sessionTicket: msg.label,
667 cipherSuite: c.cipherSuite,
668 masterSecret: c.resumptionSecret,
669 serverCertificates: c.peerCertificates,
670 verifiedChains: c.verifiedChains,
671 receivedAt: c.config.time(),
673 useBy: c.config.time().Add(lifetime),
675 ocspResponse: c.ocspResponse,
679 cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
680 c.config.ClientSessionCache.Put(cacheKey, session)