func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
	config := hs.c.config
	c := hs.c
	msg, err := c.readHandshake()
	if err != nil {
		return false, err
	}
	var ok bool
	hs.clientHello, ok = msg.(*clientHelloMsg)
	if !ok {
		return false, c.sendAlert(alertUnexpectedMessage)
	}
	c.vers, ok = config.mutualVersion(hs.clientHello.vers)
	if !ok {
		return false, c.sendAlert(alertProtocolVersion)
	}
	c.haveVers = true
	hs.finishedHash = newFinishedHash(c.vers)
	hs.finishedHash.Write(hs.clientHello.marshal())
	hs.hello = new(serverHelloMsg)
	supportedCurve := false
Curves:
	for _, curve := range hs.clientHello.supportedCurves {
		switch curve {
		case curveP256, curveP384, curveP521:
			supportedCurve = true
			break Curves
		}
	}
	supportedPointFormat := false
	for _, pointFormat := range hs.clientHello.supportedPoints {
		if pointFormat == pointFormatUncompressed {
			supportedPointFormat = true
			break
		}
	}
	hs.ellipticOk = supportedCurve && supportedPointFormat
	foundCompression := false
	for _, compression := range hs.clientHello.compressionMethods {
		if compression == compressionNone {
			foundCompression = true
			break
		}
	}
	if !foundCompression {
		return false, c.sendAlert(alertHandshakeFailure)
	}
	hs.hello.vers = c.vers
	t := uint32(config.time().Unix())
	hs.hello.random = make([]byte, 32)
	hs.hello.random[0] = byte(t >> 24)
	hs.hello.random[1] = byte(t >> 16)
	hs.hello.random[2] = byte(t >> 8)
	hs.hello.random[3] = byte(t)
	_, err = io.ReadFull(config.rand(), hs.hello.random[4:])
	if err != nil {
		return false, c.sendAlert(alertInternalError)
	}
	hs.hello.compressionMethod = compressionNone
	if len(hs.clientHello.serverName) > 0 {
		c.serverName = hs.clientHello.serverName
	}
	if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
		hs.hello.nextProtoNeg = true
		hs.hello.nextProtos = config.NextProtos
	}
	if len(config.Certificates) == 0 {
		return false, c.sendAlert(alertInternalError)
	}
	hs.cert = &config.Certificates[0]
	if len(hs.clientHello.serverName) > 0 {
		hs.cert = config.getCertificateForName(hs.clientHello.serverName)
	}
	_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
	if hs.checkForResumption() {
		return true, nil
	}
	var preferenceList, supportedList []uint16
	if c.config.PreferServerCipherSuites {
		preferenceList = c.config.cipherSuites()
		supportedList = hs.clientHello.cipherSuites
	} else {
		preferenceList = hs.clientHello.cipherSuites
		supportedList = c.config.cipherSuites()
	}
	for _, id := range preferenceList {
		if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil {
			break
		}
	}
	if hs.suite == nil {
		return false, c.sendAlert(alertHandshakeFailure)
	}
	return false, nil
}
readClientHello reads a ClientHello message from the client and decides
whether we will perform session resumption.
package tls
import (
	"crypto"
	"crypto/ecdsa"
	"crypto/rsa"
	"crypto/subtle"
	"crypto/x509"
	"encoding/asn1"
	"errors"
	"io"
)
type serverHandshakeState struct {
	c               *Conn
	clientHello     *clientHelloMsg
	hello           *serverHelloMsg
	suite           *cipherSuite
	ellipticOk      bool
	ecdsaOk         bool
	sessionState    *sessionState
	finishedHash    finishedHash
	masterSecret    []byte
	certsFromClient [][]byte
	cert            *Certificate
}
func (c *Conn) serverHandshake() error {
	config := c.config
	config.serverInitOnce.Do(config.serverInit)
	hs := serverHandshakeState{
		c: c,
	}
	isResume, err := hs.readClientHello()
	if err != nil {
		return err
	}
	if isResume {
		if err := hs.doResumeHandshake(); err != nil {
			return err
		}
		if err := hs.establishKeys(); err != nil {
			return err
		}
		if err := hs.sendFinished(); err != nil {
			return err
		}
		if err := hs.readFinished(); err != nil {
			return err
		}
		c.didResume = true
	} else {
		if err := hs.doFullHandshake(); err != nil {
			return err
		}
		if err := hs.establishKeys(); err != nil {
			return err
		}
		if err := hs.readFinished(); err != nil {
			return err
		}
		if err := hs.sendSessionTicket(); err != nil {
			return err
		}
		if err := hs.sendFinished(); err != nil {
			return err
		}
	}
	c.handshakeComplete = true
	return nil
}