package tls
import (
)
type serverHandshakeState struct {
c *Conn
ctx context.Context
clientHello *clientHelloMsg
hello *serverHelloMsg
suite *cipherSuite
ecdheOk bool
ecSignOk bool
rsaDecryptOk bool
rsaSignOk bool
sessionState *SessionState
finishedHash finishedHash
masterSecret []byte
cert *Certificate
}
func ( *Conn) ( context.Context) error {
, , := .readClientHello()
if != nil {
return
}
if .vers == VersionTLS13 {
:= serverHandshakeStateTLS13{
c: ,
ctx: ,
clientHello: ,
echContext: ,
}
return .handshake()
}
:= serverHandshakeState{
c: ,
ctx: ,
clientHello: ,
}
return .handshake()
}
func ( *serverHandshakeState) () error {
:= .c
if := .processClientHello(); != nil {
return
}
.buffering = true
if := .checkForResumption(); != nil {
return
}
if .sessionState != nil {
if := .doResumeHandshake(); != nil {
return
}
if := .establishKeys(); != nil {
return
}
if := .sendSessionTicket(); != nil {
return
}
if := .sendFinished(.serverFinished[:]); != nil {
return
}
if , := .flush(); != nil {
return
}
.clientFinishedIsFirst = false
if := .readFinished(nil); != nil {
return
}
} else {
if := .pickCipherSuite(); != nil {
return
}
if := .doFullHandshake(); != nil {
return
}
if := .establishKeys(); != nil {
return
}
if := .readFinished(.clientFinished[:]); != nil {
return
}
.clientFinishedIsFirst = true
.buffering = true
if := .sendSessionTicket(); != nil {
return
}
if := .sendFinished(nil); != nil {
return
}
if , := .flush(); != nil {
return
}
}
.ekm = ekmFromMasterSecret(.vers, .suite, .masterSecret, .clientHello.random, .hello.random)
.isHandshakeComplete.Store(true)
return nil
}
func ( *Conn) ( context.Context) (*clientHelloMsg, *echServerContext, error) {
, := .readHandshake(nil)
if != nil {
return nil, nil,
}
, := .(*clientHelloMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return nil, nil, unexpectedMessageError(, )
}
var *echServerContext
if len(.encryptedClientHello) != 0 {
, , = .processECHClientHello()
if != nil {
return nil, nil,
}
}
var *Config
:= .config
if .config.GetConfigForClient != nil {
:= clientHelloInfo(, , )
if , = .config.GetConfigForClient(); != nil {
.sendAlert(alertInternalError)
return nil, nil,
} else if != nil {
.config =
}
}
.ticketKeys = .ticketKeys()
:= .supportedVersions
if len(.supportedVersions) == 0 {
= supportedVersionsFromMax(.vers)
}
.vers, = .config.mutualVersion(roleServer, )
if ! {
.sendAlert(alertProtocolVersion)
return nil, nil, fmt.Errorf("tls: client offered only unsupported versions: %x", )
}
.haveVers = true
.in.version = .vers
.out.version = .vers
if .vers != VersionTLS13 && ( != nil && !.inner) {
.sendAlert(alertIllegalParameter)
return nil, nil, errors.New("tls: Encrypted Client Hello cannot be used pre-TLS 1.3")
}
if .config.MinVersion == 0 && .vers < VersionTLS12 {
tls10server.Value()
tls10server.IncNonDefault()
}
return , , nil
}
func ( *serverHandshakeState) () error {
:= .c
.hello = new(serverHelloMsg)
.hello.vers = .vers
:= false
for , := range .clientHello.compressionMethods {
if == compressionNone {
= true
break
}
}
if ! {
.sendAlert(alertHandshakeFailure)
return errors.New("tls: client does not support uncompressed connections")
}
.hello.random = make([]byte, 32)
:= .hello.random
:= .config.maxSupportedVersion(roleServer)
if >= VersionTLS12 && .vers < || testingOnlyForceDowngradeCanary {
if .vers == VersionTLS12 {
copy([24:], downgradeCanaryTLS12)
} else {
copy([24:], downgradeCanaryTLS11)
}
= [:24]
}
, := io.ReadFull(.config.rand(), )
if != nil {
.sendAlert(alertInternalError)
return
}
if len(.clientHello.secureRenegotiation) != 0 {
.sendAlert(alertHandshakeFailure)
return errors.New("tls: initial handshake had non-empty renegotiation extension")
}
.hello.extendedMasterSecret = .clientHello.extendedMasterSecret
.hello.secureRenegotiationSupported = .clientHello.secureRenegotiationSupported
.hello.compressionMethod = compressionNone
if len(.clientHello.serverName) > 0 {
.serverName = .clientHello.serverName
}
, := negotiateALPN(.config.NextProtos, .clientHello.alpnProtocols, false)
if != nil {
.sendAlert(alertNoApplicationProtocol)
return
}
.hello.alpnProtocol =
.clientProtocol =
.cert, = .config.getCertificate(clientHelloInfo(.ctx, , .clientHello))
if != nil {
if == errNoCertificates {
.sendAlert(alertUnrecognizedName)
} else {
.sendAlert(alertInternalError)
}
return
}
if .clientHello.scts {
.hello.scts = .cert.SignedCertificateTimestamps
}
.ecdheOk = supportsECDHE(.config, .vers, .clientHello.supportedCurves, .clientHello.supportedPoints)
if .ecdheOk && len(.clientHello.supportedPoints) > 0 {
.hello.supportedPoints = []uint8{pointFormatUncompressed}
}
if , := .cert.PrivateKey.(crypto.Signer); {
switch .Public().(type) {
case *ecdsa.PublicKey:
.ecSignOk = true
case ed25519.PublicKey:
.ecSignOk = true
case *rsa.PublicKey:
.rsaSignOk = true
default:
.sendAlert(alertInternalError)
return fmt.Errorf("tls: unsupported signing key type (%T)", .Public())
}
}
if , := .cert.PrivateKey.(crypto.Decrypter); {
switch .Public().(type) {
case *rsa.PublicKey:
.rsaDecryptOk = true
default:
.sendAlert(alertInternalError)
return fmt.Errorf("tls: unsupported decryption key type (%T)", .Public())
}
}
return nil
}
func (, []string, bool) (string, error) {
if len() == 0 || len() == 0 {
if && len() != 0 {
return "", fmt.Errorf("tls: client did not request an application protocol")
}
return "", nil
}
var bool
for , := range {
for , := range {
if == {
return , nil
}
if == "h2" && == "http/1.1" {
= true
}
}
}
if {
return "", nil
}
return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", )
}
func ( *Config, uint16, []CurveID, []uint8) bool {
:= false
for , := range {
if .supportsCurve(, ) {
= true
break
}
}
:= false
for , := range {
if == pointFormatUncompressed {
= true
break
}
}
if len() == 0 {
= true
}
return &&
}
func ( *serverHandshakeState) () error {
:= .c
:= cipherSuitesPreferenceOrder
if !hasAESGCMHardwareSupport || !aesgcmPreferred(.clientHello.cipherSuites) {
= cipherSuitesPreferenceOrderNoAES
}
:= .config.cipherSuites()
:= make([]uint16, 0, len())
for , := range {
for , := range {
if == {
= append(, )
break
}
}
}
.suite = selectCipherSuite(, .clientHello.cipherSuites, .cipherSuiteOk)
if .suite == nil {
.sendAlert(alertHandshakeFailure)
return errors.New("tls: no cipher suite supported by both client and server")
}
.cipherSuite = .suite.id
if .config.CipherSuites == nil && !fips140tls.Required() && rsaKexCiphers[.suite.id] {
tlsrsakex.Value()
tlsrsakex.IncNonDefault()
}
if .config.CipherSuites == nil && !fips140tls.Required() && tdesCiphers[.suite.id] {
tls3des.Value()
tls3des.IncNonDefault()
}
for , := range .clientHello.cipherSuites {
if == TLS_FALLBACK_SCSV {
if .clientHello.vers < .config.maxSupportedVersion(roleServer) {
.sendAlert(alertInappropriateFallback)
return errors.New("tls: client using inappropriate protocol fallback")
}
break
}
}
return nil
}
func ( *serverHandshakeState) ( *cipherSuite) bool {
if .flags&suiteECDHE != 0 {
if !.ecdheOk {
return false
}
if .flags&suiteECSign != 0 {
if !.ecSignOk {
return false
}
} else if !.rsaSignOk {
return false
}
} else if !.rsaDecryptOk {
return false
}
if .c.vers < VersionTLS12 && .flags&suiteTLS12 != 0 {
return false
}
return true
}
func ( *serverHandshakeState) () error {
:= .c
if .config.SessionTicketsDisabled {
return nil
}
var *SessionState
if .config.UnwrapSession != nil {
, := .config.UnwrapSession(.clientHello.sessionTicket, .connectionStateLocked())
if != nil {
return
}
if == nil {
return nil
}
=
} else {
:= .config.decryptTicket(.clientHello.sessionTicket, .ticketKeys)
if == nil {
return nil
}
, := ParseSessionState()
if != nil {
return nil
}
=
}
:= time.Unix(int64(.createdAt), 0)
if .config.time().Sub() > maxSessionTicketLifetime {
return nil
}
if .vers != .version {
return nil
}
:= false
for , := range .clientHello.cipherSuites {
if == .cipherSuite {
= true
break
}
}
if ! {
return nil
}
:= selectCipherSuite([]uint16{.cipherSuite},
.config.cipherSuites(), .cipherSuiteOk)
if == nil {
return nil
}
:= len(.peerCertificates) != 0
:= requiresClientCert(.config.ClientAuth)
if && ! {
return nil
}
if && .config.ClientAuth == NoClientCert {
return nil
}
if && .config.time().After(.peerCertificates[0].NotAfter) {
return nil
}
if && .config.ClientAuth >= VerifyClientCertIfGiven &&
len(.verifiedChains) == 0 {
return nil
}
if !.extMasterSecret && .clientHello.extendedMasterSecret {
return nil
}
if .extMasterSecret && !.clientHello.extendedMasterSecret {
return errors.New("tls: session supported extended_master_secret but client does not")
}
.peerCertificates = .peerCertificates
.ocspResponse = .ocspResponse
.scts = .scts
.verifiedChains = .verifiedChains
.extMasterSecret = .extMasterSecret
.sessionState =
.suite =
.didResume = true
return nil
}
func ( *serverHandshakeState) () error {
:= .c
.hello.cipherSuite = .suite.id
.cipherSuite = .suite.id
.hello.sessionId = .clientHello.sessionId
.hello.ticketSupported = true
.finishedHash = newFinishedHash(.vers, .suite)
.finishedHash.discardHandshakeBuffer()
if := transcriptMsg(.clientHello, &.finishedHash); != nil {
return
}
if , := .c.writeHandshakeRecord(.hello, &.finishedHash); != nil {
return
}
if .config.VerifyConnection != nil {
if := .config.VerifyConnection(.connectionStateLocked()); != nil {
.sendAlert(alertBadCertificate)
return
}
}
.masterSecret = .sessionState.secret
return nil
}
func ( *serverHandshakeState) () error {
:= .c
if .clientHello.ocspStapling && len(.cert.OCSPStaple) > 0 {
.hello.ocspStapling = true
}
.hello.ticketSupported = .clientHello.ticketSupported && !.config.SessionTicketsDisabled
.hello.cipherSuite = .suite.id
.finishedHash = newFinishedHash(.c.vers, .suite)
if .config.ClientAuth == NoClientCert {
.finishedHash.discardHandshakeBuffer()
}
if := transcriptMsg(.clientHello, &.finishedHash); != nil {
return
}
if , := .c.writeHandshakeRecord(.hello, &.finishedHash); != nil {
return
}
:= new(certificateMsg)
.certificates = .cert.Certificate
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
if .hello.ocspStapling {
:= new(certificateStatusMsg)
.response = .cert.OCSPStaple
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
}
:= .suite.ka(.vers)
, := .generateServerKeyExchange(.config, .cert, .clientHello, .hello)
if != nil {
.sendAlert(alertHandshakeFailure)
return
}
if != nil {
if len(.key) >= 3 && .key[0] == 3 {
.curveID = CurveID(byteorder.BEUint16(.key[1:]))
}
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
}
var *certificateRequestMsg
if .config.ClientAuth >= RequestClientCert {
= new(certificateRequestMsg)
.certificateTypes = []byte{
byte(certTypeRSASign),
byte(certTypeECDSASign),
}
if .vers >= VersionTLS12 {
.hasSignatureAlgorithm = true
.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
}
if .config.ClientCAs != nil {
.certificateAuthorities = .config.ClientCAs.Subjects()
}
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
}
:= new(serverHelloDoneMsg)
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
if , := .flush(); != nil {
return
}
var crypto.PublicKey
, := .readHandshake(&.finishedHash)
if != nil {
return
}
if .config.ClientAuth >= RequestClientCert {
, := .(*certificateMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
if := .processCertsFromClient(Certificate{
Certificate: .certificates,
}); != nil {
return
}
if len(.certificates) != 0 {
= .peerCertificates[0].PublicKey
}
, = .readHandshake(&.finishedHash)
if != nil {
return
}
}
if .config.VerifyConnection != nil {
if := .config.VerifyConnection(.connectionStateLocked()); != nil {
.sendAlert(alertBadCertificate)
return
}
}
, := .(*clientKeyExchangeMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
, := .processClientKeyExchange(.config, .cert, , .vers)
if != nil {
.sendAlert(alertIllegalParameter)
return
}
if .hello.extendedMasterSecret {
.extMasterSecret = true
.masterSecret = extMasterFromPreMasterSecret(.vers, .suite, ,
.finishedHash.Sum())
} else {
.masterSecret = masterFromPreMasterSecret(.vers, .suite, ,
.clientHello.random, .hello.random)
}
if := .config.writeKeyLog(keyLogLabelTLS12, .clientHello.random, .masterSecret); != nil {
.sendAlert(alertInternalError)
return
}
if len(.peerCertificates) > 0 {
, = .readHandshake(nil)
if != nil {
return
}
, := .(*certificateVerifyMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
var uint8
var crypto.Hash
if .vers >= VersionTLS12 {
if !isSupportedSignatureAlgorithm(.signatureAlgorithm, .supportedSignatureAlgorithms) {
.sendAlert(alertIllegalParameter)
return errors.New("tls: client certificate used with invalid signature algorithm")
}
, , = typeAndHashFromSignatureScheme(.signatureAlgorithm)
if != nil {
return .sendAlert(alertInternalError)
}
} else {
, , = legacyTypeAndHashFromPublicKey()
if != nil {
.sendAlert(alertIllegalParameter)
return
}
}
:= .finishedHash.hashForClientCertificate(, )
if := verifyHandshakeSignature(, , , , .signature); != nil {
.sendAlert(alertDecryptError)
return errors.New("tls: invalid signature by the client certificate: " + .Error())
}
if := transcriptMsg(, &.finishedHash); != nil {
return
}
}
.finishedHash.discardHandshakeBuffer()
return nil
}
func ( *serverHandshakeState) () error {
:= .c
, , , , , :=
keysFromMasterSecret(.vers, .suite, .masterSecret, .clientHello.random, .hello.random, .suite.macLen, .suite.keyLen, .suite.ivLen)
var , any
var , hash.Hash
if .suite.aead == nil {
= .suite.cipher(, , true )
= .suite.mac()
= .suite.cipher(, , false )
= .suite.mac()
} else {
= .suite.aead(, )
= .suite.aead(, )
}
.in.prepareCipherSpec(.vers, , )
.out.prepareCipherSpec(.vers, , )
return nil
}
func ( *serverHandshakeState) ( []byte) error {
:= .c
if := .readChangeCipherSpec(); != nil {
return
}
, := .readHandshake(nil)
if != nil {
return
}
, := .(*finishedMsg)
if ! {
.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(, )
}
:= .finishedHash.clientSum(.masterSecret)
if len() != len(.verifyData) ||
subtle.ConstantTimeCompare(, .verifyData) != 1 {
.sendAlert(alertHandshakeFailure)
return errors.New("tls: client's Finished message is incorrect")
}
if := transcriptMsg(, &.finishedHash); != nil {
return
}
copy(, )
return nil
}
func ( *serverHandshakeState) () error {
if !.hello.ticketSupported {
return nil
}
:= .c
:= new(newSessionTicketMsg)
:= .sessionState()
.secret = .masterSecret
if .sessionState != nil {
.createdAt = .sessionState.createdAt
}
if .config.WrapSession != nil {
var error
.ticket, = .config.WrapSession(.connectionStateLocked(), )
if != nil {
return
}
} else {
, := .Bytes()
if != nil {
return
}
.ticket, = .config.encryptTicket(, .ticketKeys)
if != nil {
return
}
}
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
return nil
}
func ( *serverHandshakeState) ( []byte) error {
:= .c
if := .writeChangeCipherRecord(); != nil {
return
}
:= new(finishedMsg)
.verifyData = .finishedHash.serverSum(.masterSecret)
if , := .c.writeHandshakeRecord(, &.finishedHash); != nil {
return
}
copy(, .verifyData)
return nil
}
func ( *Conn) ( Certificate) error {
:= .Certificate
:= make([]*x509.Certificate, len())
var error
for , := range {
if [], = x509.ParseCertificate(); != nil {
.sendAlert(alertBadCertificate)
return errors.New("tls: failed to parse client certificate: " + .Error())
}
if [].PublicKeyAlgorithm == x509.RSA {
:= [].PublicKey.(*rsa.PublicKey).N.BitLen()
if , := checkKeySize(); ! {
.sendAlert(alertBadCertificate)
return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", )
}
}
}
if len() == 0 && requiresClientCert(.config.ClientAuth) {
if .vers == VersionTLS13 {
.sendAlert(alertCertificateRequired)
} else {
.sendAlert(alertBadCertificate)
}
return errors.New("tls: client didn't provide a certificate")
}
if .config.ClientAuth >= VerifyClientCertIfGiven && len() > 0 {
:= x509.VerifyOptions{
Roots: .config.ClientCAs,
CurrentTime: .config.time(),
Intermediates: x509.NewCertPool(),
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
for , := range [1:] {
.Intermediates.AddCert()
}
, := [0].Verify()
if != nil {
var x509.CertificateInvalidError
if errors.As(, &x509.UnknownAuthorityError{}) {
.sendAlert(alertUnknownCA)
} else if errors.As(, &) && .Reason == x509.Expired {
.sendAlert(alertCertificateExpired)
} else {
.sendAlert(alertBadCertificate)
}
return &CertificateVerificationError{UnverifiedCertificates: , Err: }
}
.verifiedChains, = fipsAllowedChains()
if != nil {
.sendAlert(alertBadCertificate)
return &CertificateVerificationError{UnverifiedCertificates: , Err: }
}
}
.peerCertificates =
.ocspResponse = .OCSPStaple
.scts = .SignedCertificateTimestamps
if len() > 0 {
switch [0].PublicKey.(type) {
case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
default:
.sendAlert(alertUnsupportedCertificate)
return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", [0].PublicKey)
}
}
if .config.VerifyPeerCertificate != nil {
if := .config.VerifyPeerCertificate(, .verifiedChains); != nil {
.sendAlert(alertBadCertificate)
return
}
}
return nil
}
func ( context.Context, *Conn, *clientHelloMsg) *ClientHelloInfo {
:= .supportedVersions
if len(.supportedVersions) == 0 {
= supportedVersionsFromMax(.vers)
}
return &ClientHelloInfo{
CipherSuites: .cipherSuites,
ServerName: .serverName,
SupportedCurves: .supportedCurves,
SupportedPoints: .supportedPoints,
SignatureSchemes: .supportedSignatureAlgorithms,
SupportedProtos: .alpnProtocols,
SupportedVersions: ,
Extensions: .extensions,
Conn: .conn,
config: .config,
ctx: ,
}
}