// clientHandshake handles the client side of the handshake.
// Note the connection can be closed while this is running.
// Returns a SQLError.
341615
func (c *Conn) clientHandshake(characterSet uint8, params *ConnParams) error {
	// Wait for the server initial handshake packet, and parse it.
	data, err := c.readPacket()
	if err != nil {
		return NewSQLError(CRServerLost, "", "initial packet read failed: %v", err)
	}
	capabilities, salt, err := c.parseInitialHandshakePacket(data)
	if err != nil {
		return err
	}

	// Sanity check.
	if capabilities&CapabilityClientProtocol41 == 0 {
		return NewSQLError(CRVersionError, SSUnknownSQLState, "cannot connect to servers earlier than 4.1")
	}

	// Remember a subset of the capabilities, so we can use them
	// later in the protocol.
	c.Capabilities = 0
	if !params.DisableClientDeprecateEOF {
		c.Capabilities = capabilities & (CapabilityClientDeprecateEOF)
	}

	// Handle switch to SSL if necessary.
	if params.Flags&CapabilityClientSSL > 0 {
		// If client asked for SSL, but server doesn't support it,
		// stop right here.
		if capabilities&CapabilityClientSSL == 0 {
			return NewSQLError(CRSSLConnectionError, SSUnknownSQLState, "server doesn't support SSL but client asked for it")
		}

		// The ServerName to verify depends on what the hostname is.
		// We use the params's ServerName if specified. Otherwise:
		// - If using a socket, we use "localhost".
		// - If it is an IP address, we need to prefix it with 'IP:'.
		// - If not, we can just use it as is.
		serverName := "localhost"
		if params.ServerName != "" {
			serverName = params.ServerName
		} else if params.Host != "" {
			if net.ParseIP(params.Host) != nil {
				serverName = "IP:" + params.Host
			} else {
				serverName = params.Host
			}
		}

		// Build the TLS config.
		clientConfig, err := vttls.ClientConfig(params.SslCert, params.SslKey, params.SslCa, serverName)
		if err != nil {
			return NewSQLError(CRSSLConnectionError, SSUnknownSQLState, "error loading client cert and ca: %v", err)
		}

		// Send the SSLRequest packet.
		if err := c.writeSSLRequest(capabilities, characterSet, params); err != nil {
			return err
		}

		// Switch to SSL.
		conn := tls.Client(c.conn, clientConfig)
		c.conn = conn
		c.bufferedReader.Reset(conn)
		c.Capabilities |= CapabilityClientSSL
	}

	// Password encryption.
	scrambledPassword := ScramblePassword(salt, []byte(params.Pass))

	// Build and send our handshake response 41.
	// Note this one will never have SSL flag on.
	if err := c.writeHandshakeResponse41(capabilities, scrambledPassword, characterSet, params); err != nil {
		return err
	}

	// Read the server response.
	response, err := c.readPacket()
	if err != nil {
		return NewSQLError(CRServerLost, SSUnknownSQLState, "%v", err)
	}
	switch response[0] {
	case OKPacket:
		// OK packet, we are authenticated. Save the user, keep going.
		c.User = params.Uname
	case AuthSwitchRequestPacket:
		// Server is asking to use a different auth method. We
		// only support cleartext plugin.
		pluginName, _, err := parseAuthSwitchRequest(response)
		if err != nil {
			return NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "cannot parse auth switch request: %v", err)
		}
		if pluginName != MysqlClearPassword {
			return NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "server asked for unsupported auth method: %v", pluginName)
		}

		// Write the password packet.
		if err := c.writeClearTextPassword(params); err != nil {
			return err
		}

		// Wait for OK packet.
		response, err = c.readPacket()
		if err != nil {
			return NewSQLError(CRServerLost, SSUnknownSQLState, "%v", err)
		}
		switch response[0] {
		case OKPacket:
			// OK packet, we are authenticated. Save the user, keep going.
			c.User = params.Uname
		case ErrPacket:
			return ParseErrorPacket(response)
		default:
			return NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "initial server response cannot be parsed: %v", response)
		}
	case ErrPacket:
		return ParseErrorPacket(response)
	default:
		return NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "initial server response cannot be parsed: %v", response)
	}

	// If the server didn't support DbName in its handshake, set
	// it now. This is what the 'mysql' client does.
	if capabilities&CapabilityClientConnectWithDB == 0 && params.DbName != "" {
		// Write the packet.
		if err := c.writeComInitDB(params.DbName); err != nil {
			return err
		}

		// Wait for response, should be OK.
		response, err := c.readPacket()
		if err != nil {
			return NewSQLError(CRServerLost, SSUnknownSQLState, "%v", err)
		}
		switch response[0] {
		case OKPacket:
			// OK packet, we are authenticated.
			return nil
		case ErrPacket:
			return ParseErrorPacket(response)
		default:
			// FIXME(alainjobart) handle extra auth cases and so on.
			return NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "initial server response is asking for more information, not implemented yet: %v", response)
		}
	}

	return nil
}
142918
func (c *Client) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
	return c.Transporter.Handshake(conn, options...)
}
477918
func (c *ConnectionStore) verifyHandshake(endpoint string, certificate []byte) RemoteVerifier {
	return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
		if bytes.Equal(certificate, rawCerts[0]) {
			return nil
		}
		return errors.Errorf("certificate presented by %s doesn't match any authorized certificate", endpoint)
	}
}
1096278
func Handshake(conn net.Conn) (string, error) {
	// Read in the version and reject anything other than SOCKS5.
	version, err := readByte(conn)
	if err != nil {
		return "", trace.Wrap(err)
	}
	if version != socks5Version {
		return "", trace.BadParameter("only SOCKS5 is supported")
	}

	// Read in the authentication method requested by the client and write back
	// the method that was selected. At the moment only "no authentication
	// required" is supported.
	authMethods, err := readAuthenticationMethod(conn)
	if err != nil {
		return "", trace.Wrap(err)
	}
	if !byteSliceContains(authMethods, socks5AuthNotRequired) {
		return "", trace.BadParameter("only 'no authentication required' is supported")
	}
	err = writeMethodSelection(conn)
	if err != nil {
		return "", trace.Wrap(err)
	}

	// Read in the request from the client and make sure the requested command
	// is supported and extract the remote address. If everything is good, write
	// out a success response.
	remoteAddr, err := readRequest(conn)
	if err != nil {
		return "", trace.Wrap(err)
	}
	err = writeReply(conn)
	if err != nil {
		return "", trace.Wrap(err)
	}

	return remoteAddr, nil
}
75241
func (c *Conn) Handshake() error {
	c.handshakeMutex.Lock()
	defer c.handshakeMutex.Unlock()
	if err := c.handshakeErr; err != nil {
		return err
	}
	if c.handshakeComplete {
		return nil
	}

	if c.isClient {
		c.handshakeErr = c.clientHandshake()
	} else {
		c.handshakeErr = c.serverHandshake()
	}
	return c.handshakeErr
}
1216731
func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {
	if config.ClientVersion != "" {
		c.clientVersion = []byte(config.ClientVersion)
	} else {
		c.clientVersion = []byte(packageVersion)
	}
	var err error
	c.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)
	if err != nil {
		return err
	}

	c.transport = newClientTransport(
		newTransport(c.sshConn.conn, config.Rand, true /* is client */),
		c.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())
	if err := c.transport.requestKeyChange(); err != nil {
		return err
	}

	if packet, err := c.transport.readPacket(); err != nil {
		return err
	} else if packet[0] != msgNewKeys {
		return unexpectedMessageError(msgNewKeys, packet[0])
	}

	// We just did the key change, so the session ID is established.
	c.sessionID = c.transport.getSessionID()

	return c.clientAuthenticate(config)
}
2701
func sendHandshake(conn *net.TCPConn, infoHash, peerID []byte) error {
	data := make([]byte, 68)
	copy(data[:28], handshakePrefix)
	copy(data[28:48], infoHash)
	copy(data[48:], peerID)

	conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
	_, err := conn.Write(data)
	return err
}
620676
func (s *CancelHandshakeOutput) SetHandshake(v *Handshake) *CancelHandshakeOutput {
	s.Handshake = v
	return s
}
396655
func (s *DeclineHandshakeOutput) SetHandshake(v *Handshake) *DeclineHandshakeOutput {
	s.Handshake = v
	return s
}
878306
func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) {
	if len(config.hostKeys) == 0 {
		return nil, errors.New("ssh: server has no host keys")
	}

	if !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil && config.KeyboardInteractiveCallback == nil {
		return nil, errors.New("ssh: no authentication methods configured but NoClientAuth is also false")
	}

	if config.ServerVersion != "" {
		s.serverVersion = []byte(config.ServerVersion)
	} else {
		s.serverVersion = []byte(packageVersion)
	}
	var err error
	s.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion)
	if err != nil {
		return nil, err
	}

	tr := newTransport(s.sshConn.conn, config.Rand, false /* not client */)
	s.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config)

	if err := s.transport.requestKeyChange(); err != nil {
		return nil, err
	}

	if packet, err := s.transport.readPacket(); err != nil {
		return nil, err
	} else if packet[0] != msgNewKeys {
		return nil, unexpectedMessageError(msgNewKeys, packet[0])
	}

	// We just did the key change, so the session ID is established.
	s.sessionID = s.transport.getSessionID()

	var packet []byte
	if packet, err = s.transport.readPacket(); err != nil {
		return nil, err
	}

	var serviceRequest serviceRequestMsg
	if err = Unmarshal(packet, &serviceRequest); err != nil {
		return nil, err
	}
	if serviceRequest.Service != serviceUserAuth {
		return nil, errors.New("ssh: requested service '" + serviceRequest.Service + "' before authenticating")
	}
	serviceAccept := serviceAcceptMsg{
		Service: serviceUserAuth,
	}
	if err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil {
		return nil, err
	}

	perms, err := s.serverAuthenticate(config)
	if err != nil {
		return nil, err
	}
	s.mux = newMux(s.transport)
	return perms, err
}
582636
func (s *DescribeHandshakeOutput) SetHandshake(v *Handshake) *DescribeHandshakeOutput {
	s.Handshake = v
	return s
}
1087936
func (api *HandshakeAPI) GetHandshakePublicKey(symkeyid string) (string, error) {
	storekey := api.ctrl.getSymKey(symkeyid)
	if storekey == nil {
		return "", fmt.Errorf("invalid symkey id %s", symkeyid)
	}
	return *storekey.pubKeyID, nil
}
967596
func (tc *clientTransportCredentials) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
	return nil, nil, ServerHandshakeNopErr
}
760745
func IsHandshakeFailedError(err error) bool {
	if err == nil {
		return false
	}
	return strings.Contains(trace.Unwrap(err).Error(), "ssh: handshake failed")
}
405076
func (g *altsTC) ServerHandshake(rawConn net.Conn) (_ net.Conn, _ credentials.AuthInfo, err error) {
	if !vmOnGCP {
		return nil, nil, ErrUntrustedPlatform
	}
	// Connecting to ALTS handshaker service.
	hsConn, err := service.Dial(g.hsAddress)
	if err != nil {
		return nil, nil, err
	}
	// Do not close hsConn since it's shared with other handshakes.

	ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
	defer cancel()
	opts := handshaker.DefaultServerHandshakerOptions()
	opts.RPCVersions = &altspb.RpcProtocolVersions{
		MaxRpcVersion: maxRPCVersion,
		MinRpcVersion: minRPCVersion,
	}
	shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, opts)
	defer func() {
		if err != nil {
			shs.Close()
		}
	}()
	if err != nil {
		return nil, nil, err
	}
	secConn, authInfo, err := shs.ServerHandshake(ctx)
	if err != nil {
		return nil, nil, err
	}
	altsAuthInfo, ok := authInfo.(AuthInfo)
	if !ok {
		return nil, nil, errors.New("server-side auth info is not of type alts.AuthInfo")
	}
	match, _ := checkRPCVersions(opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
	if !match {
		return nil, nil, fmt.Errorf("client-side RPC versions is not compatible with this server, local versions: %v, peer versions: %v", opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
	}
	return secConn, authInfo, nil
}
1357963
func NewServerHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, opts *ServerHandshakerOptions) (core.Handshaker, error) {
	stream, err := altsgrpc.NewHandshakerServiceClient(conn).DoHandshake(ctx, grpc.WaitForReady(true))
	if err != nil {
		return nil, err
	}
	return &altsHandshaker{
		stream:     stream,
		conn:       c,
		serverOpts: opts,
		side:       core.ServerSide,
	}, nil
}
1132762
func newHandshakeState(initiator bool, prologue []byte,
	localPub *btcec.PrivateKey, remotePub *btcec.PublicKey) handshakeState {

	h := handshakeState{
		initiator:    initiator,
		localStatic:  localPub,
		remoteStatic: remotePub,
	}

	// Set the current chaining key and handshake digest to the hash of the
	// protocol name, and additionally mix in the prologue. If either sides
	// disagree about the prologue or protocol name, then the handshake
	// will fail.
	h.InitializeSymmetric([]byte(protocolName))
	h.mixHash(prologue)

	// In Noise_XK, then initiator should know the responder's static
	// public key, therefore we include the responder's static key in the
	// handshake digest. If the initiator gets this value wrong, then the
	// handshake will fail.
	if initiator {
		h.mixHash(remotePub.SerializeCompressed())
	} else {
		h.mixHash(localPub.PubKey().SerializeCompressed())
	}

	return h
}