...

Source file src/github.com/tjfoc/gmsm/gmtls/handshake_server.go

Documentation: github.com/tjfoc/gmsm/gmtls

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

View as plain text