// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package tls import ( "bytes" "context" "crypto" "crypto/hmac" "crypto/internal/mlkem768" "crypto/rsa" "errors" "hash" "internal/byteorder" "io" "slices" "time" ) // maxClientPSKIdentities is the number of client PSK identities the server will // attempt to validate. It will ignore the rest not to let cheap ClientHello // messages cause too much work in session ticket decryption attempts. const maxClientPSKIdentities = 5 type serverHandshakeStateTLS13 struct { c *Conn ctx context.Context clientHello *clientHelloMsg hello *serverHelloMsg sentDummyCCS bool usingPSK bool earlyData bool suite *cipherSuiteTLS13 cert *Certificate sigAlg SignatureScheme earlySecret []byte sharedKey []byte handshakeSecret []byte masterSecret []byte trafficSecret []byte // client_application_traffic_secret_0 transcript hash.Hash clientFinished []byte } func (hs *serverHandshakeStateTLS13) handshake() error { c := hs.c // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. if err := hs.processClientHello(); err != nil { return err } if err := hs.checkForResumption(); err != nil { return err } if err := hs.pickCertificate(); err != nil { return err } c.buffering = true if err := hs.sendServerParameters(); err != nil { return err } if err := hs.sendServerCertificate(); err != nil { return err } if err := hs.sendServerFinished(); err != nil { return err } // Note that at this point we could start sending application data without // waiting for the client's second flight, but the application might not // expect the lack of replay protection of the ClientHello parameters. if _, err := c.flush(); err != nil { return err } if err := hs.readClientCertificate(); err != nil { return err } if err := hs.readClientFinished(); err != nil { return err } c.isHandshakeComplete.Store(true) return nil } func (hs *serverHandshakeStateTLS13) processClientHello() error { c := hs.c hs.hello = new(serverHelloMsg) // TLS 1.3 froze the ServerHello.legacy_version field, and uses // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1. hs.hello.vers = VersionTLS12 hs.hello.supportedVersion = c.vers if len(hs.clientHello.supportedVersions) == 0 { c.sendAlert(alertIllegalParameter) return errors.New("tls: client used the legacy version field to negotiate TLS 1.3") } // Abort if the client is doing a fallback and landing lower than what we // support. See RFC 7507, which however does not specify the interaction // with supported_versions. The only difference is that with // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to // TLS 1.2, because a TLS 1.3 server would abort here. The situation before // supported_versions was not better because there was just no way to do a // TLS 1.4 handshake without risking the server selecting TLS 1.3. for _, id := range hs.clientHello.cipherSuites { if id == TLS_FALLBACK_SCSV { // Use c.vers instead of max(supported_versions) because an attacker // could defeat this by adding an arbitrary high version otherwise. if c.vers < c.config.maxSupportedVersion(roleServer) { c.sendAlert(alertInappropriateFallback) return errors.New("tls: client using inappropriate protocol fallback") } break } } if len(hs.clientHello.compressionMethods) != 1 || hs.clientHello.compressionMethods[0] != compressionNone { c.sendAlert(alertIllegalParameter) return errors.New("tls: TLS 1.3 client supports illegal compression methods") } hs.hello.random = make([]byte, 32) if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil { c.sendAlert(alertInternalError) return err } if len(hs.clientHello.secureRenegotiation) != 0 { c.sendAlert(alertHandshakeFailure) return errors.New("tls: initial handshake had non-empty renegotiation extension") } if hs.clientHello.earlyData && c.quic != nil { if len(hs.clientHello.pskIdentities) == 0 { c.sendAlert(alertIllegalParameter) return errors.New("tls: early_data without pre_shared_key") } } else if hs.clientHello.earlyData { // See RFC 8446, Section 4.2.10 for the complicated behavior required // here. The scenario is that a different server at our address offered // to accept early data in the past, which we can't handle. For now, all // 0-RTT enabled session tickets need to expire before a Go server can // replace a server or join a pool. That's the same requirement that // applies to mixing or replacing with any TLS 1.2 server. c.sendAlert(alertUnsupportedExtension) return errors.New("tls: client sent unexpected early data") } hs.hello.sessionId = hs.clientHello.sessionId hs.hello.compressionMethod = compressionNone preferenceList := defaultCipherSuitesTLS13 if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { preferenceList = defaultCipherSuitesTLS13NoAES } if needFIPS() { preferenceList = defaultCipherSuitesTLS13FIPS } for _, suiteID := range preferenceList { hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID) if hs.suite != nil { break } } if hs.suite == nil { c.sendAlert(alertHandshakeFailure) return errors.New("tls: no cipher suite supported by both client and server") } c.cipherSuite = hs.suite.id hs.hello.cipherSuite = hs.suite.id hs.transcript = hs.suite.hash.New() // Pick the key exchange method in server preference order, but give // priority to key shares, to avoid a HelloRetryRequest round-trip. var selectedGroup CurveID var clientKeyShare *keyShare preferredGroups := c.config.curvePreferences(c.vers) for _, preferredGroup := range preferredGroups { ki := slices.IndexFunc(hs.clientHello.keyShares, func(ks keyShare) bool { return ks.group == preferredGroup }) if ki != -1 { clientKeyShare = &hs.clientHello.keyShares[ki] selectedGroup = clientKeyShare.group if !slices.Contains(hs.clientHello.supportedCurves, selectedGroup) { c.sendAlert(alertIllegalParameter) return errors.New("tls: client sent key share for group it does not support") } break } } if selectedGroup == 0 { for _, preferredGroup := range preferredGroups { if slices.Contains(hs.clientHello.supportedCurves, preferredGroup) { selectedGroup = preferredGroup break } } } if selectedGroup == 0 { c.sendAlert(alertHandshakeFailure) return errors.New("tls: no ECDHE curve supported by both client and server") } if clientKeyShare == nil { ks, err := hs.doHelloRetryRequest(selectedGroup) if err != nil { return err } clientKeyShare = ks } c.curveID = selectedGroup ecdhGroup := selectedGroup ecdhData := clientKeyShare.data if selectedGroup == x25519Kyber768Draft00 { ecdhGroup = X25519 if len(ecdhData) != x25519PublicKeySize+mlkem768.EncapsulationKeySize { c.sendAlert(alertIllegalParameter) return errors.New("tls: invalid Kyber client key share") } ecdhData = ecdhData[:x25519PublicKeySize] } if _, ok := curveForCurveID(ecdhGroup); !ok { c.sendAlert(alertInternalError) return errors.New("tls: CurvePreferences includes unsupported curve") } key, err := generateECDHEKey(c.config.rand(), ecdhGroup) if err != nil { c.sendAlert(alertInternalError) return err } hs.hello.serverShare = keyShare{group: selectedGroup, data: key.PublicKey().Bytes()} peerKey, err := key.Curve().NewPublicKey(ecdhData) if err != nil { c.sendAlert(alertIllegalParameter) return errors.New("tls: invalid client key share") } hs.sharedKey, err = key.ECDH(peerKey) if err != nil { c.sendAlert(alertIllegalParameter) return errors.New("tls: invalid client key share") } if selectedGroup == x25519Kyber768Draft00 { ciphertext, kyberShared, err := kyberEncapsulate(clientKeyShare.data[x25519PublicKeySize:]) if err != nil { c.sendAlert(alertIllegalParameter) return errors.New("tls: invalid Kyber client key share") } hs.sharedKey = append(hs.sharedKey, kyberShared...) hs.hello.serverShare.data = append(hs.hello.serverShare.data, ciphertext...) } selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, c.quic != nil) if err != nil { c.sendAlert(alertNoApplicationProtocol) return err } c.clientProtocol = selectedProto if c.quic != nil { // RFC 9001 Section 4.2: Clients MUST NOT offer TLS versions older than 1.3. for _, v := range hs.clientHello.supportedVersions { if v < VersionTLS13 { c.sendAlert(alertProtocolVersion) return errors.New("tls: client offered TLS version older than TLS 1.3") } } // RFC 9001 Section 8.2. if hs.clientHello.quicTransportParameters == nil { c.sendAlert(alertMissingExtension) return errors.New("tls: client did not send a quic_transport_parameters extension") } c.quicSetTransportParameters(hs.clientHello.quicTransportParameters) } else { if hs.clientHello.quicTransportParameters != nil { c.sendAlert(alertUnsupportedExtension) return errors.New("tls: client sent an unexpected quic_transport_parameters extension") } } c.serverName = hs.clientHello.serverName return nil } func (hs *serverHandshakeStateTLS13) checkForResumption() error { c := hs.c if c.config.SessionTicketsDisabled { return nil } modeOK := false for _, mode := range hs.clientHello.pskModes { if mode == pskModeDHE { modeOK = true break } } if !modeOK { return nil } if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { c.sendAlert(alertIllegalParameter) return errors.New("tls: invalid or missing PSK binders") } if len(hs.clientHello.pskIdentities) == 0 { return nil } for i, identity := range hs.clientHello.pskIdentities { if i >= maxClientPSKIdentities { break } var sessionState *SessionState if c.config.UnwrapSession != nil { var err error sessionState, err = c.config.UnwrapSession(identity.label, c.connectionStateLocked()) if err != nil { return err } if sessionState == nil { continue } } else { plaintext := c.config.decryptTicket(identity.label, c.ticketKeys) if plaintext == nil { continue } var err error sessionState, err = ParseSessionState(plaintext) if err != nil { continue } } if sessionState.version != VersionTLS13 { continue } createdAt := time.Unix(int64(sessionState.createdAt), 0) if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { continue } pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) if pskSuite == nil || pskSuite.hash != hs.suite.hash { continue } // PSK connections don't re-establish client certificates, but carry // them over in the session ticket. Ensure the presence of client certs // in the ticket is consistent with the configured requirements. sessionHasClientCerts := len(sessionState.peerCertificates) != 0 needClientCerts := requiresClientCert(c.config.ClientAuth) if needClientCerts && !sessionHasClientCerts { continue } if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { continue } if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) { continue } if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven && len(sessionState.verifiedChains) == 0 { continue } if c.quic != nil && c.quic.enableSessionEvents { if err := c.quicResumeSession(sessionState); err != nil { return err } } hs.earlySecret = hs.suite.extract(sessionState.secret, nil) binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil) // Clone the transcript in case a HelloRetryRequest was recorded. transcript := cloneHash(hs.transcript, hs.suite.hash) if transcript == nil { c.sendAlert(alertInternalError) return errors.New("tls: internal error: failed to clone hash") } clientHelloBytes, err := hs.clientHello.marshalWithoutBinders() if err != nil { c.sendAlert(alertInternalError) return err } transcript.Write(clientHelloBytes) pskBinder := hs.suite.finishedHash(binderKey, transcript) if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { c.sendAlert(alertDecryptError) return errors.New("tls: invalid PSK binder") } if c.quic != nil && hs.clientHello.earlyData && i == 0 && sessionState.EarlyData && sessionState.cipherSuite == hs.suite.id && sessionState.alpnProtocol == c.clientProtocol { hs.earlyData = true transcript := hs.suite.hash.New() if err := transcriptMsg(hs.clientHello, transcript); err != nil { return err } earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript) c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret) } c.didResume = true c.peerCertificates = sessionState.peerCertificates c.ocspResponse = sessionState.ocspResponse c.scts = sessionState.scts c.verifiedChains = sessionState.verifiedChains hs.hello.selectedIdentityPresent = true hs.hello.selectedIdentity = uint16(i) hs.usingPSK = true return nil } return nil } // cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler // interfaces implemented by standard library hashes to clone the state of in // to a new instance of h. It returns nil if the operation fails. func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash { // Recreate the interface to avoid importing encoding. type binaryMarshaler interface { MarshalBinary() (data []byte, err error) UnmarshalBinary(data []byte) error } marshaler, ok := in.(binaryMarshaler) if !ok { return nil } state, err := marshaler.MarshalBinary() if err != nil { return nil } out := h.New() unmarshaler, ok := out.(binaryMarshaler) if !ok { return nil } if err := unmarshaler.UnmarshalBinary(state); err != nil { return nil } return out } func (hs *serverHandshakeStateTLS13) pickCertificate() error { c := hs.c // Only one of PSK and certificates are used at a time. if hs.usingPSK { return nil } // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3. if len(hs.clientHello.supportedSignatureAlgorithms) == 0 { return c.sendAlert(alertMissingExtension) } certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello)) if err != nil { if err == errNoCertificates { c.sendAlert(alertUnrecognizedName) } else { c.sendAlert(alertInternalError) } return err } hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms) if err != nil { // getCertificate returned a certificate that is unsupported or // incompatible with the client's signature algorithms. c.sendAlert(alertHandshakeFailure) return err } hs.cert = certificate return nil } // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error { if hs.c.quic != nil { return nil } if hs.sentDummyCCS { return nil } hs.sentDummyCCS = true return hs.c.writeChangeCipherRecord() } func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) (*keyShare, error) { c := hs.c // The first ClientHello gets double-hashed into the transcript upon a // HelloRetryRequest. See RFC 8446, Section 4.4.1. if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil { return nil, err } chHash := hs.transcript.Sum(nil) hs.transcript.Reset() hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) hs.transcript.Write(chHash) helloRetryRequest := &serverHelloMsg{ vers: hs.hello.vers, random: helloRetryRequestRandom, sessionId: hs.hello.sessionId, cipherSuite: hs.hello.cipherSuite, compressionMethod: hs.hello.compressionMethod, supportedVersion: hs.hello.supportedVersion, selectedGroup: selectedGroup, } if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, hs.transcript); err != nil { return nil, err } if err := hs.sendDummyChangeCipherSpec(); err != nil { return nil, err } // clientHelloMsg is not included in the transcript. msg, err := c.readHandshake(nil) if err != nil { return nil, err } clientHello, ok := msg.(*clientHelloMsg) if !ok { c.sendAlert(alertUnexpectedMessage) return nil, unexpectedMessageError(clientHello, msg) } if len(clientHello.keyShares) != 1 { c.sendAlert(alertIllegalParameter) return nil, errors.New("tls: client didn't send one key share in second ClientHello") } ks := &clientHello.keyShares[0] if ks.group != selectedGroup { c.sendAlert(alertIllegalParameter) return nil, errors.New("tls: client sent unexpected key share in second ClientHello") } if clientHello.earlyData { c.sendAlert(alertIllegalParameter) return nil, errors.New("tls: client indicated early data in second ClientHello") } if illegalClientHelloChange(clientHello, hs.clientHello) { c.sendAlert(alertIllegalParameter) return nil, errors.New("tls: client illegally modified second ClientHello") } c.didHRR = true hs.clientHello = clientHello return ks, nil } // illegalClientHelloChange reports whether the two ClientHello messages are // different, with the exception of the changes allowed before and after a // HelloRetryRequest. See RFC 8446, Section 4.1.2. func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { if len(ch.supportedVersions) != len(ch1.supportedVersions) || len(ch.cipherSuites) != len(ch1.cipherSuites) || len(ch.supportedCurves) != len(ch1.supportedCurves) || len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) || len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) || len(ch.alpnProtocols) != len(ch1.alpnProtocols) { return true } for i := range ch.supportedVersions { if ch.supportedVersions[i] != ch1.supportedVersions[i] { return true } } for i := range ch.cipherSuites { if ch.cipherSuites[i] != ch1.cipherSuites[i] { return true } } for i := range ch.supportedCurves { if ch.supportedCurves[i] != ch1.supportedCurves[i] { return true } } for i := range ch.supportedSignatureAlgorithms { if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] { return true } } for i := range ch.supportedSignatureAlgorithmsCert { if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] { return true } } for i := range ch.alpnProtocols { if ch.alpnProtocols[i] != ch1.alpnProtocols[i] { return true } } return ch.vers != ch1.vers || !bytes.Equal(ch.random, ch1.random) || !bytes.Equal(ch.sessionId, ch1.sessionId) || !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || ch.serverName != ch1.serverName || ch.ocspStapling != ch1.ocspStapling || !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || ch.ticketSupported != ch1.ticketSupported || !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) || ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported || !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) || ch.scts != ch1.scts || !bytes.Equal(ch.cookie, ch1.cookie) || !bytes.Equal(ch.pskModes, ch1.pskModes) } func (hs *serverHandshakeStateTLS13) sendServerParameters() error { c := hs.c if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil { return err } if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil { return err } if err := hs.sendDummyChangeCipherSpec(); err != nil { return err } earlySecret := hs.earlySecret if earlySecret == nil { earlySecret = hs.suite.extract(nil, nil) } hs.handshakeSecret = hs.suite.extract(hs.sharedKey, hs.suite.deriveSecret(earlySecret, "derived", nil)) clientSecret := hs.suite.deriveSecret(hs.handshakeSecret, clientHandshakeTrafficLabel, hs.transcript) c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret) serverSecret := hs.suite.deriveSecret(hs.handshakeSecret, serverHandshakeTrafficLabel, hs.transcript) c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret) if c.quic != nil { if c.hand.Len() != 0 { c.sendAlert(alertUnexpectedMessage) } c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret) c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret) } err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret) if err != nil { c.sendAlert(alertInternalError) return err } err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret) if err != nil { c.sendAlert(alertInternalError) return err } encryptedExtensions := new(encryptedExtensionsMsg) encryptedExtensions.alpnProtocol = c.clientProtocol if c.quic != nil { p, err := c.quicGetTransportParameters() if err != nil { return err } encryptedExtensions.quicTransportParameters = p encryptedExtensions.earlyData = hs.earlyData } if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil { return err } return nil } func (hs *serverHandshakeStateTLS13) requestClientCert() bool { return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK } func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { c := hs.c // Only one of PSK and certificates are used at a time. if hs.usingPSK { return nil } if hs.requestClientCert() { // Request a client certificate certReq := new(certificateRequestMsgTLS13) certReq.ocspStapling = true certReq.scts = true certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms() if c.config.ClientCAs != nil { certReq.certificateAuthorities = c.config.ClientCAs.Subjects() } if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); err != nil { return err } } certMsg := new(certificateMsgTLS13) certMsg.certificate = *hs.cert certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil { return err } certVerifyMsg := new(certificateVerifyMsg) certVerifyMsg.hasSignatureAlgorithm = true certVerifyMsg.signatureAlgorithm = hs.sigAlg sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg) if err != nil { return c.sendAlert(alertInternalError) } signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) signOpts := crypto.SignerOpts(sigHash) if sigType == signatureRSAPSS { signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} } sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) if err != nil { public := hs.cert.PrivateKey.(crypto.Signer).Public() if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS && rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS c.sendAlert(alertHandshakeFailure) } else { c.sendAlert(alertInternalError) } return errors.New("tls: failed to sign handshake: " + err.Error()) } certVerifyMsg.signature = sig if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil { return err } return nil } func (hs *serverHandshakeStateTLS13) sendServerFinished() error { c := hs.c finished := &finishedMsg{ verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), } if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil { return err } // Derive secrets that take context through the server Finished. hs.masterSecret = hs.suite.extract(nil, hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil)) hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, clientApplicationTrafficLabel, hs.transcript) serverSecret := hs.suite.deriveSecret(hs.masterSecret, serverApplicationTrafficLabel, hs.transcript) c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret) if c.quic != nil { if c.hand.Len() != 0 { // TODO: Handle this in setTrafficSecret? c.sendAlert(alertUnexpectedMessage) } c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, serverSecret) } err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret) if err != nil { c.sendAlert(alertInternalError) return err } err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret) if err != nil { c.sendAlert(alertInternalError) return err } c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) // If we did not request client certificates, at this point we can // precompute the client finished and roll the transcript forward to send // session tickets in our first flight. if !hs.requestClientCert() { if err := hs.sendSessionTickets(); err != nil { return err } } return nil } func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool { if hs.c.config.SessionTicketsDisabled { return false } // QUIC tickets are sent by QUICConn.SendSessionTicket, not automatically. if hs.c.quic != nil { return false } // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9. for _, pskMode := range hs.clientHello.pskModes { if pskMode == pskModeDHE { return true } } return false } func (hs *serverHandshakeStateTLS13) sendSessionTickets() error { c := hs.c hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) finishedMsg := &finishedMsg{ verifyData: hs.clientFinished, } if err := transcriptMsg(finishedMsg, hs.transcript); err != nil { return err } c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, resumptionLabel, hs.transcript) if !hs.shouldSendSessionTickets() { return nil } return c.sendSessionTicket(false, nil) } func (c *Conn) sendSessionTicket(earlyData bool, extra [][]byte) error { suite := cipherSuiteTLS13ByID(c.cipherSuite) if suite == nil { return errors.New("tls: internal error: unknown cipher suite") } // ticket_nonce, which must be unique per connection, is always left at // zero because we only ever send one ticket per connection. psk := suite.expandLabel(c.resumptionSecret, "resumption", nil, suite.hash.Size()) m := new(newSessionTicketMsgTLS13) state := c.sessionState() state.secret = psk state.EarlyData = earlyData state.Extra = extra if c.config.WrapSession != nil { var err error m.label, err = c.config.WrapSession(c.connectionStateLocked(), state) if err != nil { return err } } else { stateBytes, err := state.Bytes() if err != nil { c.sendAlert(alertInternalError) return err } m.label, err = c.config.encryptTicket(stateBytes, c.ticketKeys) if err != nil { return err } } m.lifetime = uint32(maxSessionTicketLifetime / time.Second) // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1 // The value is not stored anywhere; we never need to check the ticket age // because 0-RTT is not supported. ageAdd := make([]byte, 4) if _, err := c.config.rand().Read(ageAdd); err != nil { return err } m.ageAdd = byteorder.LeUint32(ageAdd) if earlyData { // RFC 9001, Section 4.6.1 m.maxEarlyData = 0xffffffff } if _, err := c.writeHandshakeRecord(m, nil); err != nil { return err } return nil } func (hs *serverHandshakeStateTLS13) readClientCertificate() error { c := hs.c if !hs.requestClientCert() { // Make sure the connection is still being verified whether or not // the server requested a client certificate. if c.config.VerifyConnection != nil { if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { c.sendAlert(alertBadCertificate) return err } } return nil } // If we requested a client certificate, then the client must send a // certificate message. If it's empty, no CertificateVerify is sent. msg, err := c.readHandshake(hs.transcript) if err != nil { return err } certMsg, ok := msg.(*certificateMsgTLS13) if !ok { c.sendAlert(alertUnexpectedMessage) return unexpectedMessageError(certMsg, msg) } if err := c.processCertsFromClient(certMsg.certificate); err != nil { return err } if c.config.VerifyConnection != nil { if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { c.sendAlert(alertBadCertificate) return err } } if len(certMsg.certificate.Certificate) != 0 { // certificateVerifyMsg is included in the transcript, but not until // after we verify the handshake signature, since the state before // this message was sent is used. msg, err = c.readHandshake(nil) if err != nil { return err } certVerify, ok := msg.(*certificateVerifyMsg) if !ok { c.sendAlert(alertUnexpectedMessage) return unexpectedMessageError(certVerify, msg) } // See RFC 8446, Section 4.4.3. if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) { c.sendAlert(alertIllegalParameter) return errors.New("tls: client certificate used with invalid signature algorithm") } sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) if err != nil { return c.sendAlert(alertInternalError) } if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { c.sendAlert(alertIllegalParameter) return errors.New("tls: client certificate used with invalid signature algorithm") } signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, sigHash, signed, certVerify.signature); err != nil { c.sendAlert(alertDecryptError) return errors.New("tls: invalid signature by the client certificate: " + err.Error()) } if err := transcriptMsg(certVerify, hs.transcript); err != nil { return err } } // If we waited until the client certificates to send session tickets, we // are ready to do it now. if err := hs.sendSessionTickets(); err != nil { return err } return nil } func (hs *serverHandshakeStateTLS13) readClientFinished() error { c := hs.c // finishedMsg is not included in the transcript. msg, err := c.readHandshake(nil) if err != nil { return err } finished, ok := msg.(*finishedMsg) if !ok { c.sendAlert(alertUnexpectedMessage) return unexpectedMessageError(finished, msg) } if !hmac.Equal(hs.clientFinished, finished.verifyData) { c.sendAlert(alertDecryptError) return errors.New("tls: invalid client finished hash") } c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret) return nil }