github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/gmtls/handshake_server.go (about)

     1  /*
     2  Copyright Suzhou Tongji Fintech Research Institute 2017 All Rights Reserved.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6  
     7  	http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  package gmtls
    17  
    18  import (
    19  	"crypto"
    20  	"crypto/ecdsa"
    21  	"crypto/rsa"
    22  	"crypto/subtle"
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  
    27  	"github.com/Hyperledger-TWGC/tjfoc-gm/x509"
    28  )
    29  
    30  // serverHandshakeState contains details of a server handshake in progress.
    31  // It's discarded once the handshake has completed.
    32  type serverHandshakeState struct {
    33  	c                     *Conn
    34  	clientHello           *clientHelloMsg
    35  	hello                 *serverHelloMsg
    36  	suite                 *cipherSuite
    37  	ellipticOk            bool
    38  	ecdsaOk               bool
    39  	rsaDecryptOk          bool
    40  	rsaSignOk             bool
    41  	sessionState          *sessionState
    42  	finishedHash          finishedHash
    43  	masterSecret          []byte
    44  	certsFromClient       [][]byte
    45  	cert                  *Certificate
    46  	cachedClientHelloInfo *ClientHelloInfo
    47  }
    48  
    49  // serverHandshake performs a TLS handshake as a server.
    50  // c.out.Mutex <= L; c.handshakeMutex <= L.
    51  func (c *Conn) serverHandshake() error {
    52  	// If this is the first server handshake, we generate a random key to
    53  	// encrypt the tickets with.
    54  	c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) })
    55  
    56  	hs := serverHandshakeState{
    57  		c: c,
    58  	}
    59  	isResume, err := hs.readClientHello()
    60  	if err != nil {
    61  		return err
    62  	}
    63  
    64  	// For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
    65  	c.buffering = true
    66  	if isResume {
    67  		// The client has included a session ticket and so we do an abbreviated handshake.
    68  		if err := hs.doResumeHandshake(); err != nil {
    69  			return err
    70  		}
    71  		if err := hs.establishKeys(); err != nil {
    72  			return err
    73  		}
    74  		// ticketSupported is set in a resumption handshake if the
    75  		// ticket from the client was encrypted with an old session
    76  		// ticket key and thus a refreshed ticket should be sent.
    77  		if hs.hello.ticketSupported {
    78  			if err := hs.sendSessionTicket(); err != nil {
    79  				return err
    80  			}
    81  		}
    82  		if err := hs.sendFinished(c.serverFinished[:]); err != nil {
    83  			return err
    84  		}
    85  		if _, err := c.flush(); err != nil {
    86  			return err
    87  		}
    88  		c.clientFinishedIsFirst = false
    89  		if err := hs.readFinished(nil); err != nil {
    90  			return err
    91  		}
    92  		c.didResume = true
    93  	} else {
    94  		// The client didn't include a session ticket, or it wasn't
    95  		// valid so we do a full handshake.
    96  		if err := hs.doFullHandshake(); err != nil {
    97  			return err
    98  		}
    99  		if err := hs.establishKeys(); err != nil {
   100  			return err
   101  		}
   102  		if err := hs.readFinished(c.clientFinished[:]); err != nil {
   103  			return err
   104  		}
   105  		c.clientFinishedIsFirst = true
   106  		c.buffering = true
   107  		if err := hs.sendSessionTicket(); err != nil {
   108  			return err
   109  		}
   110  		if err := hs.sendFinished(nil); err != nil {
   111  			return err
   112  		}
   113  		if _, err := c.flush(); err != nil {
   114  			return err
   115  		}
   116  	}
   117  	return nil
   118  }
   119  
   120  // readClientHello reads a ClientHello message from the client and decides
   121  // whether we will perform session resumption.
   122  func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
   123  	c := hs.c
   124  
   125  	msg, err := c.readHandshake()
   126  	if err != nil {
   127  		return false, err
   128  	}
   129  	var ok bool
   130  	hs.clientHello, ok = msg.(*clientHelloMsg)
   131  	if !ok {
   132  		c.sendAlert(alertUnexpectedMessage)
   133  		return false, unexpectedMessageError(hs.clientHello, msg)
   134  	}
   135  
   136  	if c.config.GetConfigForClient != nil {
   137  		if newConfig, err := c.config.GetConfigForClient(hs.clientHelloInfo()); err != nil {
   138  			c.sendAlert(alertInternalError)
   139  			return false, err
   140  		} else if newConfig != nil {
   141  			newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) })
   142  			c.config = newConfig
   143  		}
   144  	}
   145  
   146  	c.vers, ok = c.config.mutualVersion(hs.clientHello.vers)
   147  	if !ok {
   148  		c.sendAlert(alertProtocolVersion)
   149  		return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
   150  	}
   151  	c.haveVers = true
   152  
   153  	hs.hello = new(serverHelloMsg)
   154  
   155  	supportedCurve := false
   156  	preferredCurves := c.config.curvePreferences()
   157  Curves:
   158  	for _, curve := range hs.clientHello.supportedCurves {
   159  		for _, supported := range preferredCurves {
   160  			if supported == curve {
   161  				supportedCurve = true
   162  				break Curves
   163  			}
   164  		}
   165  	}
   166  
   167  	supportedPointFormat := false
   168  	for _, pointFormat := range hs.clientHello.supportedPoints {
   169  		if pointFormat == pointFormatUncompressed {
   170  			supportedPointFormat = true
   171  			break
   172  		}
   173  	}
   174  	hs.ellipticOk = supportedCurve && supportedPointFormat
   175  
   176  	foundCompression := false
   177  	// We only support null compression, so check that the client offered it.
   178  	for _, compression := range hs.clientHello.compressionMethods {
   179  		if compression == compressionNone {
   180  			foundCompression = true
   181  			break
   182  		}
   183  	}
   184  
   185  	if !foundCompression {
   186  		c.sendAlert(alertHandshakeFailure)
   187  		return false, errors.New("tls: client does not support uncompressed connections")
   188  	}
   189  
   190  	hs.hello.vers = c.vers
   191  	hs.hello.random = make([]byte, 32)
   192  	_, err = io.ReadFull(c.config.rand(), hs.hello.random)
   193  	if err != nil {
   194  		c.sendAlert(alertInternalError)
   195  		return false, err
   196  	}
   197  
   198  	if len(hs.clientHello.secureRenegotiation) != 0 {
   199  		c.sendAlert(alertHandshakeFailure)
   200  		return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
   201  	}
   202  
   203  	hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
   204  	hs.hello.compressionMethod = compressionNone
   205  	if len(hs.clientHello.serverName) > 0 {
   206  		c.serverName = hs.clientHello.serverName
   207  	}
   208  
   209  	if len(hs.clientHello.alpnProtocols) > 0 {
   210  		if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
   211  			hs.hello.alpnProtocol = selectedProto
   212  			c.clientProtocol = selectedProto
   213  		}
   214  	} else {
   215  		// Although sending an empty NPN extension is reasonable, Firefox has
   216  		// had a bug around this. Best to send nothing at all if
   217  		// c.config.NextProtos is empty. See
   218  		// https://golang.org/issue/5445.
   219  		if hs.clientHello.nextProtoNeg && len(c.config.NextProtos) > 0 {
   220  			hs.hello.nextProtoNeg = true
   221  			hs.hello.nextProtos = c.config.NextProtos
   222  		}
   223  	}
   224  
   225  	hs.cert, err = c.config.getCertificate(hs.clientHelloInfo())
   226  	if err != nil {
   227  		c.sendAlert(alertInternalError)
   228  		return false, err
   229  	}
   230  	if hs.clientHello.scts {
   231  		hs.hello.scts = hs.cert.SignedCertificateTimestamps
   232  	}
   233  
   234  	if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
   235  		switch priv.Public().(type) {
   236  		case *ecdsa.PublicKey:
   237  			hs.ecdsaOk = true
   238  		case *rsa.PublicKey:
   239  			hs.rsaSignOk = true
   240  		default:
   241  			c.sendAlert(alertInternalError)
   242  			return false, fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
   243  		}
   244  	}
   245  	if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
   246  		switch priv.Public().(type) {
   247  		case *rsa.PublicKey:
   248  			hs.rsaDecryptOk = true
   249  		default:
   250  			c.sendAlert(alertInternalError)
   251  			return false, fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
   252  		}
   253  	}
   254  
   255  	if hs.checkForResumption() {
   256  		return true, nil
   257  	}
   258  
   259  	var preferenceList, supportedList []uint16
   260  	if c.config.PreferServerCipherSuites {
   261  		preferenceList = c.config.cipherSuites()
   262  		supportedList = hs.clientHello.cipherSuites
   263  	} else {
   264  		preferenceList = hs.clientHello.cipherSuites
   265  		supportedList = c.config.cipherSuites()
   266  	}
   267  
   268  	for _, id := range preferenceList {
   269  		if hs.setCipherSuite(id, supportedList, c.vers) {
   270  			break
   271  		}
   272  	}
   273  
   274  	if hs.suite == nil {
   275  		c.sendAlert(alertHandshakeFailure)
   276  		return false, errors.New("tls: no cipher suite supported by both client and server")
   277  	}
   278  
   279  	// See https://tools.ietf.org/html/rfc7507.
   280  	for _, id := range hs.clientHello.cipherSuites {
   281  		if id == TLS_FALLBACK_SCSV {
   282  			// The client is doing a fallback connection.
   283  			if hs.clientHello.vers < c.config.maxVersion() {
   284  				c.sendAlert(alertInappropriateFallback)
   285  				return false, errors.New("tls: client using inappropriate protocol fallback")
   286  			}
   287  			break
   288  		}
   289  	}
   290  
   291  	return false, nil
   292  }
   293  
   294  // checkForResumption reports whether we should perform resumption on this connection.
   295  func (hs *serverHandshakeState) checkForResumption() bool {
   296  	c := hs.c
   297  
   298  	if c.config.SessionTicketsDisabled {
   299  		return false
   300  	}
   301  
   302  	var ok bool
   303  	var sessionTicket = append([]uint8{}, hs.clientHello.sessionTicket...)
   304  	if hs.sessionState, ok = c.decryptTicket(sessionTicket); !ok {
   305  		return false
   306  	}
   307  
   308  	// Never resume a session for a different TLS version.
   309  	if c.vers != hs.sessionState.vers {
   310  		return false
   311  	}
   312  
   313  	cipherSuiteOk := false
   314  	// Check that the client is still offering the ciphersuite in the session.
   315  	for _, id := range hs.clientHello.cipherSuites {
   316  		if id == hs.sessionState.cipherSuite {
   317  			cipherSuiteOk = true
   318  			break
   319  		}
   320  	}
   321  	if !cipherSuiteOk {
   322  		return false
   323  	}
   324  
   325  	// Check that we also support the ciphersuite from the session.
   326  	if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) {
   327  		return false
   328  	}
   329  
   330  	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
   331  	needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
   332  	if needClientCerts && !sessionHasClientCerts {
   333  		return false
   334  	}
   335  	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
   336  		return false
   337  	}
   338  
   339  	return true
   340  }
   341  
   342  func (hs *serverHandshakeState) doResumeHandshake() error {
   343  	c := hs.c
   344  
   345  	hs.hello.cipherSuite = hs.suite.id
   346  	// We echo the client's session ID in the ServerHello to let it know
   347  	// that we're doing a resumption.
   348  	hs.hello.sessionId = hs.clientHello.sessionId
   349  	hs.hello.ticketSupported = hs.sessionState.usedOldKey
   350  	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
   351  	hs.finishedHash.discardHandshakeBuffer()
   352  	hs.finishedHash.Write(hs.clientHello.marshal())
   353  	hs.finishedHash.Write(hs.hello.marshal())
   354  	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
   355  		return err
   356  	}
   357  
   358  	if len(hs.sessionState.certificates) > 0 {
   359  		if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
   360  			return err
   361  		}
   362  	}
   363  
   364  	hs.masterSecret = hs.sessionState.masterSecret
   365  
   366  	return nil
   367  }
   368  
   369  func (hs *serverHandshakeState) doFullHandshake() error {
   370  	c := hs.c
   371  
   372  	if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
   373  		hs.hello.ocspStapling = true
   374  	}
   375  
   376  	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
   377  	hs.hello.cipherSuite = hs.suite.id
   378  
   379  	hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
   380  	if c.config.ClientAuth == NoClientCert {
   381  		// No need to keep a full record of the handshake if client
   382  		// certificates won't be used.
   383  		hs.finishedHash.discardHandshakeBuffer()
   384  	}
   385  	hs.finishedHash.Write(hs.clientHello.marshal())
   386  	hs.finishedHash.Write(hs.hello.marshal())
   387  	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
   388  		return err
   389  	}
   390  
   391  	certMsg := new(certificateMsg)
   392  	certMsg.certificates = hs.cert.Certificate
   393  	hs.finishedHash.Write(certMsg.marshal())
   394  	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
   395  		return err
   396  	}
   397  
   398  	if hs.hello.ocspStapling {
   399  		certStatus := new(certificateStatusMsg)
   400  		certStatus.statusType = statusTypeOCSP
   401  		certStatus.response = hs.cert.OCSPStaple
   402  		hs.finishedHash.Write(certStatus.marshal())
   403  		if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
   404  			return err
   405  		}
   406  	}
   407  
   408  	keyAgreement := hs.suite.ka(c.vers)
   409  	skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert,hs.cert, hs.clientHello, hs.hello)
   410  	if err != nil {
   411  		c.sendAlert(alertHandshakeFailure)
   412  		return err
   413  	}
   414  	if skx != nil {
   415  		hs.finishedHash.Write(skx.marshal())
   416  		if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
   417  			return err
   418  		}
   419  	}
   420  
   421  	if c.config.ClientAuth >= RequestClientCert {
   422  		// Request a client certificate
   423  		certReq := new(certificateRequestMsg)
   424  		certReq.certificateTypes = []byte{
   425  			byte(certTypeRSASign),
   426  			byte(certTypeECDSASign),
   427  		}
   428  		if c.vers >= VersionTLS12 {
   429  			certReq.hasSignatureAndHash = true
   430  			certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
   431  		}
   432  
   433  		// An empty list of certificateAuthorities signals to
   434  		// the client that it may send any certificate in response
   435  		// to our request. When we know the CAs we trust, then
   436  		// we can send them down, so that the client can choose
   437  		// an appropriate certificate to give to us.
   438  		if c.config.ClientCAs != nil {
   439  			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
   440  		}
   441  		hs.finishedHash.Write(certReq.marshal())
   442  		if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
   443  			return err
   444  		}
   445  	}
   446  
   447  	helloDone := new(serverHelloDoneMsg)
   448  	hs.finishedHash.Write(helloDone.marshal())
   449  	if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
   450  		return err
   451  	}
   452  
   453  	if _, err := c.flush(); err != nil {
   454  		return err
   455  	}
   456  
   457  	var pub crypto.PublicKey // public key for client auth, if any
   458  
   459  	msg, err := c.readHandshake()
   460  	if err != nil {
   461  		return err
   462  	}
   463  
   464  	var ok bool
   465  	// If we requested a client certificate, then the client must send a
   466  	// certificate message, even if it's empty.
   467  	if c.config.ClientAuth >= RequestClientCert {
   468  		if certMsg, ok = msg.(*certificateMsg); !ok {
   469  			c.sendAlert(alertUnexpectedMessage)
   470  			return unexpectedMessageError(certMsg, msg)
   471  		}
   472  		hs.finishedHash.Write(certMsg.marshal())
   473  
   474  		if len(certMsg.certificates) == 0 {
   475  			// The client didn't actually send a certificate
   476  			switch c.config.ClientAuth {
   477  			case RequireAnyClientCert, RequireAndVerifyClientCert:
   478  				c.sendAlert(alertBadCertificate)
   479  				return errors.New("tls: client didn't provide a certificate")
   480  			}
   481  		}
   482  
   483  		pub, err = hs.processCertsFromClient(certMsg.certificates)
   484  		if err != nil {
   485  			return err
   486  		}
   487  
   488  		msg, err = c.readHandshake()
   489  		if err != nil {
   490  			return err
   491  		}
   492  	}
   493  
   494  	// Get client key exchange
   495  	ckx, ok := msg.(*clientKeyExchangeMsg)
   496  	if !ok {
   497  		c.sendAlert(alertUnexpectedMessage)
   498  		return unexpectedMessageError(ckx, msg)
   499  	}
   500  	hs.finishedHash.Write(ckx.marshal())
   501  
   502  	preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
   503  	if err != nil {
   504  		c.sendAlert(alertHandshakeFailure)
   505  		return err
   506  	}
   507  	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
   508  	if err := c.config.writeKeyLog(hs.clientHello.random, hs.masterSecret); err != nil {
   509  		c.sendAlert(alertInternalError)
   510  		return err
   511  	}
   512  
   513  	// If we received a client cert in response to our certificate request message,
   514  	// the client will send us a certificateVerifyMsg immediately after the
   515  	// clientKeyExchangeMsg. This message is a digest of all preceding
   516  	// handshake-layer messages that is signed using the private key corresponding
   517  	// to the client's certificate. This allows us to verify that the client is in
   518  	// possession of the private key of the certificate.
   519  	if len(c.peerCertificates) > 0 {
   520  		msg, err = c.readHandshake()
   521  		if err != nil {
   522  			return err
   523  		}
   524  		certVerify, ok := msg.(*certificateVerifyMsg)
   525  		if !ok {
   526  			c.sendAlert(alertUnexpectedMessage)
   527  			return unexpectedMessageError(certVerify, msg)
   528  		}
   529  
   530  		// Determine the signature type.
   531  		_, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, supportedSignatureAlgorithms, c.vers)
   532  		if err != nil {
   533  			c.sendAlert(alertIllegalParameter)
   534  			return err
   535  		}
   536  
   537  		var digest []byte
   538  		if digest, err = hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret); err == nil {
   539  			err = verifyHandshakeSignature(sigType, pub, hashFunc, digest, certVerify.signature)
   540  		}
   541  		if err != nil {
   542  			c.sendAlert(alertBadCertificate)
   543  			return errors.New("tls: could not validate signature of connection nonces: " + err.Error())
   544  		}
   545  
   546  		hs.finishedHash.Write(certVerify.marshal())
   547  	}
   548  
   549  	hs.finishedHash.discardHandshakeBuffer()
   550  
   551  	return nil
   552  }
   553  
   554  func (hs *serverHandshakeState) establishKeys() error {
   555  	c := hs.c
   556  
   557  	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
   558  		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
   559  
   560  	var clientCipher, serverCipher interface{}
   561  	var clientHash, serverHash macFunction
   562  
   563  	if hs.suite.aead == nil {
   564  		clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
   565  		clientHash = hs.suite.mac(c.vers, clientMAC)
   566  		serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
   567  		serverHash = hs.suite.mac(c.vers, serverMAC)
   568  	} else {
   569  		clientCipher = hs.suite.aead(clientKey, clientIV)
   570  		serverCipher = hs.suite.aead(serverKey, serverIV)
   571  	}
   572  
   573  	c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
   574  	c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
   575  
   576  	return nil
   577  }
   578  
   579  func (hs *serverHandshakeState) readFinished(out []byte) error {
   580  	c := hs.c
   581  
   582  	c.readRecord(recordTypeChangeCipherSpec)
   583  	if c.in.err != nil {
   584  		return c.in.err
   585  	}
   586  
   587  	if hs.hello.nextProtoNeg {
   588  		msg, err := c.readHandshake()
   589  		if err != nil {
   590  			return err
   591  		}
   592  		nextProto, ok := msg.(*nextProtoMsg)
   593  		if !ok {
   594  			c.sendAlert(alertUnexpectedMessage)
   595  			return unexpectedMessageError(nextProto, msg)
   596  		}
   597  		hs.finishedHash.Write(nextProto.marshal())
   598  		c.clientProtocol = nextProto.proto
   599  	}
   600  
   601  	msg, err := c.readHandshake()
   602  	if err != nil {
   603  		return err
   604  	}
   605  	clientFinished, ok := msg.(*finishedMsg)
   606  	if !ok {
   607  		c.sendAlert(alertUnexpectedMessage)
   608  		return unexpectedMessageError(clientFinished, msg)
   609  	}
   610  
   611  	verify := hs.finishedHash.clientSum(hs.masterSecret)
   612  	if len(verify) != len(clientFinished.verifyData) ||
   613  		subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
   614  		c.sendAlert(alertHandshakeFailure)
   615  		return errors.New("tls: client's Finished message is incorrect")
   616  	}
   617  
   618  	hs.finishedHash.Write(clientFinished.marshal())
   619  	copy(out, verify)
   620  	return nil
   621  }
   622  
   623  func (hs *serverHandshakeState) sendSessionTicket() error {
   624  	if !hs.hello.ticketSupported {
   625  		return nil
   626  	}
   627  
   628  	c := hs.c
   629  	m := new(newSessionTicketMsg)
   630  
   631  	var err error
   632  	state := sessionState{
   633  		vers:         c.vers,
   634  		cipherSuite:  hs.suite.id,
   635  		masterSecret: hs.masterSecret,
   636  		certificates: hs.certsFromClient,
   637  	}
   638  	m.ticket, err = c.encryptTicket(&state)
   639  	if err != nil {
   640  		return err
   641  	}
   642  
   643  	hs.finishedHash.Write(m.marshal())
   644  	if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
   645  		return err
   646  	}
   647  
   648  	return nil
   649  }
   650  
   651  func (hs *serverHandshakeState) sendFinished(out []byte) error {
   652  	c := hs.c
   653  
   654  	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
   655  		return err
   656  	}
   657  
   658  	finished := new(finishedMsg)
   659  	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
   660  	hs.finishedHash.Write(finished.marshal())
   661  	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
   662  		return err
   663  	}
   664  
   665  	c.cipherSuite = hs.suite.id
   666  	copy(out, finished.verifyData)
   667  
   668  	return nil
   669  }
   670  
   671  // processCertsFromClient takes a chain of client certificates either from a
   672  // Certificates message or from a sessionState and verifies them. It returns
   673  // the public key of the leaf certificate.
   674  func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
   675  	c := hs.c
   676  
   677  	hs.certsFromClient = certificates
   678  	certs := make([]*x509.Certificate, len(certificates))
   679  	var err error
   680  	for i, asn1Data := range certificates {
   681  		if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
   682  			c.sendAlert(alertBadCertificate)
   683  			return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
   684  		}
   685  	}
   686  
   687  	if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
   688  		opts := x509.VerifyOptions{
   689  			Roots:         c.config.ClientCAs,
   690  			CurrentTime:   c.config.time(),
   691  			Intermediates: x509.NewCertPool(),
   692  			KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
   693  		}
   694  
   695  		for _, cert := range certs[1:] {
   696  			opts.Intermediates.AddCert(cert)
   697  		}
   698  
   699  		chains, err := certs[0].Verify(opts)
   700  		if err != nil {
   701  			c.sendAlert(alertBadCertificate)
   702  			return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
   703  		}
   704  
   705  		c.verifiedChains = chains
   706  	}
   707  
   708  	if c.config.VerifyPeerCertificate != nil {
   709  		if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
   710  			c.sendAlert(alertBadCertificate)
   711  			return nil, err
   712  		}
   713  	}
   714  
   715  	if len(certs) == 0 {
   716  		return nil, nil
   717  	}
   718  
   719  	var pub crypto.PublicKey
   720  	switch key := certs[0].PublicKey.(type) {
   721  	case *ecdsa.PublicKey, *rsa.PublicKey:
   722  		pub = key
   723  	default:
   724  		c.sendAlert(alertUnsupportedCertificate)
   725  		return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
   726  	}
   727  	c.peerCertificates = certs
   728  	return pub, nil
   729  }
   730  
   731  // setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState
   732  // suite if that cipher suite is acceptable to use.
   733  // It returns a bool indicating if the suite was set.
   734  func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool {
   735  	for _, supported := range supportedCipherSuites {
   736  		if id == supported {
   737  			var candidate *cipherSuite
   738  
   739  			for _, s := range cipherSuites {
   740  				if s.id == id {
   741  					candidate = s
   742  					break
   743  				}
   744  			}
   745  			if candidate == nil {
   746  				continue
   747  			}
   748  			// Don't select a ciphersuite which we can't
   749  			// support for this client.
   750  			if candidate.flags&suiteECDHE != 0 {
   751  				if !hs.ellipticOk {
   752  					continue
   753  				}
   754  				if candidate.flags&suiteECDSA != 0 {
   755  					if !hs.ecdsaOk {
   756  						continue
   757  					}
   758  				} else if !hs.rsaSignOk {
   759  					continue
   760  				}
   761  			} else if !hs.rsaDecryptOk {
   762  				continue
   763  			}
   764  			if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
   765  				continue
   766  			}
   767  			hs.suite = candidate
   768  			return true
   769  		}
   770  	}
   771  	return false
   772  }
   773  
   774  // suppVersArray is the backing array of ClientHelloInfo.SupportedVersions
   775  var suppVersArray = [...]uint16{VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30}
   776  
   777  func (hs *serverHandshakeState) clientHelloInfo() *ClientHelloInfo {
   778  	if hs.cachedClientHelloInfo != nil {
   779  		return hs.cachedClientHelloInfo
   780  	}
   781  
   782  	var supportedVersions []uint16
   783  	if hs.clientHello.vers > VersionTLS12 {
   784  		supportedVersions = suppVersArray[:]
   785  	} else if hs.clientHello.vers >= VersionSSL30 {
   786  		supportedVersions = suppVersArray[VersionTLS12-hs.clientHello.vers:]
   787  	}
   788  
   789  	hs.cachedClientHelloInfo = &ClientHelloInfo{
   790  		CipherSuites:      hs.clientHello.cipherSuites,
   791  		ServerName:        hs.clientHello.serverName,
   792  		SupportedCurves:   hs.clientHello.supportedCurves,
   793  		SupportedPoints:   hs.clientHello.supportedPoints,
   794  		SignatureSchemes:  hs.clientHello.supportedSignatureAlgorithms,
   795  		SupportedProtos:   hs.clientHello.alpnProtocols,
   796  		SupportedVersions: supportedVersions,
   797  		Conn:              hs.c.conn,
   798  	}
   799  
   800  	return hs.cachedClientHelloInfo
   801  }