// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vif

import (
	"io"

	"v.io/v23/naming"
	"v.io/v23/rpc/version"
	"v.io/v23/security"
	"v.io/v23/verror"

	"v.io/x/ref/runtime/internal/lib/iobuf"
	"v.io/x/ref/runtime/internal/rpc/stream"
	"v.io/x/ref/runtime/internal/rpc/stream/crypto"
	"v.io/x/ref/runtime/internal/rpc/stream/message"
	"v.io/x/ref/runtime/internal/rpc/stream/vc"
	iversion "v.io/x/ref/runtime/internal/rpc/version"
)

var (
	// These errors are intended to be used as arguments to higher
	// level errors and hence {1}{2} is omitted from their format
	// strings to avoid repeating these n-times in the final error
	// message visible to the user.
	errAuthFailed                      = reg(".errAuthFailed", "authentication failed{:3}")
	errUnsupportedEncryptVersion       = reg(".errUnsupportedEncryptVersion", "unsupported encryption version {4} < {5}")
	errNaclBoxVersionNegotiationFailed = reg(".errNaclBoxVersionNegotiationFailed", "nacl box encryption version negotiation failed")
	errVersionNegotiationFailed        = reg(".errVersionNegotiationFailed", "encryption version negotiation failed")
	nullCipher                         crypto.NullControlCipher
)

// AuthenticationResult includes the result of the VIF authentication.
type AuthenticationResult struct {
	Dialed           bool
	Version          version.RPCVersion
	RemoteEndpoint   naming.Endpoint
	SessionKeys      SessionKeys
	LocalBlessings   security.Blessings
	RemoteBlessings  security.Blessings
	LocalDischarges  map[string]security.Discharge
	RemoteDischarges map[string]security.Discharge
}

// Public/private keys used to establish an encrypted communication channel
// (and not the keys corresponding to the principal used in authentication).
type SessionKeys struct {
	LocalPublic, LocalPrivate, RemotePublic crypto.BoxKey
}

// AuthenticateAsClient sends a Setup message if possible. If so, it chooses
// encryption based on the max supported version.
//
// The sequence is initiated by the client.
//
//    - The client sends a Setup message to the server, containing the client's
//      supported versions, and the client's crypto options. The Setup message
//      is sent in the clear.
//
//    - When the server receives the Setup message, it calls
//      AuthenticateAsServer, which constructs a response Setup containing
//      the server's version range, and any crypto options.
//
//    - The client and server use the public/private key pairs
//      generated for the Setup messages to create an encrypted stream
//      of SetupStream messages for the remainder of the authentication
//      setup. The encryption uses NewControlCipherRPC11, which is based
//      on code.google.com/p/go.crypto/nacl/box.
//
//    - Once the encrypted SetupStream channel is setup, the client and
//      server authenticate using the vc.AuthenticateAs{Client,Server} protocol.
//
// Note that the Setup messages are sent in the clear, so they are subject to
// modification by a man-in-the-middle, which can currently force a downgrade by
// modifying the acceptable version ranges downward.  This can be addressed by
// including a hash of the Setup message in the encrypted stream.  It is
// likely that this will be addressed in subsequent protocol versions.
func AuthenticateAsClient(writer io.Writer, reader *iobuf.Reader, localEP naming.Endpoint, versions *iversion.Range, principal security.Principal, auth *vc.ServerAuthorizer) (crypto.ControlCipher, *AuthenticationResult, error) {
	if versions == nil {
		versions = iversion.SupportedRange
	}

	// Send the client's public data.
	setup, pk, sk, err := makeSetup(versions, localEP)
	if err != nil {
		return nil, nil, verror.New(stream.ErrSecurity, nil, err)
	}

	errch := make(chan error, 1)
	go func() {
		errch <- message.WriteTo(writer, setup, nullCipher)
	}()

	remoteMsg, err := message.ReadFrom(reader, nullCipher)
	if err != nil {
		return nil, nil, verror.New(stream.ErrNetwork, nil, err)
	}
	remoteSetup, ok := remoteMsg.(*message.Setup)
	if !ok {
		return nil, nil, verror.New(stream.ErrSecurity, nil, verror.New(errVersionNegotiationFailed, nil))
	}

	// Wait for the write to succeed.
	if err := <-errch; err != nil {
		return nil, nil, verror.New(stream.ErrNetwork, nil, err)
	}

	// Choose the max version in the intersection.
	vrange, err := setup.Versions.Intersect(&remoteSetup.Versions)
	if err != nil {
		return nil, nil, verror.New(stream.ErrNetwork, nil, err)
	}

	if principal == nil {
		return nullCipher, nil, nil
	}

	// Perform the authentication.
	ver := vrange.Max
	remoteBox := remoteSetup.NaclBox()
	if remoteBox == nil {
		return nil, nil, verror.New(errNaclBoxVersionNegotiationFailed, nil)
	}
	remoteEP := remoteSetup.PeerEndpoint()

	var cipher crypto.ControlCipher
	switch {
	case ver < version.RPCVersion11:
		cipher = crypto.NewControlCipherRPC6(sk, &remoteBox.PublicKey, false)
	default:
		cipher = crypto.NewControlCipherRPC11(pk, sk, &remoteBox.PublicKey)
	}
	sconn := newSetupConn(writer, reader, cipher)
	crypter := crypto.NewNullCrypterWithChannelBinding(cipher.ChannelBinding())
	params := security.CallParams{LocalPrincipal: principal, LocalEndpoint: localEP}
	// TODO(jyh): act upon the authentication results.
	lBlessings, rBlessings, rDischarges, err := vc.AuthenticateAsClient(sconn, crypter, ver, params, auth)
	if err != nil {
		return nil, nil, err
	}
	if ver < version.RPCVersion11 || remoteEP == nil {
		// We do not return AuthenticationResult for old versions due to a channel binding bug.
		return cipher, nil, nil
	}

	authr := AuthenticationResult{
		Dialed:         true,
		Version:        ver,
		RemoteEndpoint: remoteEP,
		SessionKeys: SessionKeys{
			RemotePublic: remoteBox.PublicKey,
		},
		LocalBlessings:   lBlessings,
		RemoteBlessings:  rBlessings,
		RemoteDischarges: rDischarges,
	}
	return cipher, &authr, nil
}

// AuthenticateAsServer handles a Setup message, choosing authentication
// based on the max common version.
//
// See AuthenticateAsClient for a description of the negotiation.
func AuthenticateAsServer(writer io.Writer, reader *iobuf.Reader, localEP naming.Endpoint, versions *iversion.Range, principal security.Principal, lBlessings security.Blessings, dc vc.DischargeClient) (crypto.ControlCipher, *AuthenticationResult, error) {
	if versions == nil {
		versions = iversion.SupportedRange
	}

	// Send server's public data.
	setup, pk, sk, err := makeSetup(versions, localEP)
	if err != nil {
		return nil, nil, err
	}

	errch := make(chan error, 1)
	readch := make(chan struct{})
	go func() {
		// TODO(mattr,ribrdb): In the case of the agent, which is
		// currently the only user of insecure connections, we need to
		// wait for the client to initiate the communication.  The agent
		// sends an extra first byte to clients, which clients read before
		// dialing their side of the vif.  If we send this message before
		// the magic byte has been sent the client will use the first
		// byte of this message instead rendering the remainder of the
		// stream uninterpretable.
		if principal == nil {
			<-readch
		}
		errch <- message.WriteTo(writer, setup, nullCipher)
	}()

	// Read client's public data.
	remoteMsg, err := message.ReadFrom(reader, nullCipher)
	close(readch) // Note: we need to close this whether we get an error or not.
	if err != nil {
		return nil, nil, verror.New(stream.ErrNetwork, nil, err)
	}
	remoteSetup, ok := remoteMsg.(*message.Setup)
	if !ok {
		return nil, nil, verror.New(stream.ErrSecurity, nil, verror.New(errVersionNegotiationFailed, nil))
	}

	// Wait for the write to succeed.
	if err := <-errch; err != nil {
		return nil, nil, err
	}

	// Choose the max version in the intersection.
	vrange, err := versions.Intersect(&remoteSetup.Versions)
	if err != nil {
		return nil, nil, verror.New(stream.ErrNetwork, nil, err)
	}

	if principal == nil {
		return nullCipher, nil, nil
	}

	// Perform authentication.
	ver := vrange.Max
	remoteBox := remoteSetup.NaclBox()
	if remoteBox == nil {
		return nil, nil, verror.New(errNaclBoxVersionNegotiationFailed, nil)
	}
	remoteEP := remoteSetup.PeerEndpoint()

	var cipher crypto.ControlCipher
	switch {
	case ver < version.RPCVersion11:
		cipher = crypto.NewControlCipherRPC6(sk, &remoteBox.PublicKey, true)
	default:
		cipher = crypto.NewControlCipherRPC11(pk, sk, &remoteBox.PublicKey)
	}
	sconn := newSetupConn(writer, reader, cipher)
	crypter := crypto.NewNullCrypterWithChannelBinding(cipher.ChannelBinding())
	// TODO(jyh): act upon authentication results.
	rBlessings, lDischarges, err := vc.AuthenticateAsServer(sconn, crypter, ver, principal, lBlessings, dc)
	if err != nil {
		return nil, nil, verror.New(errAuthFailed, nil, err)
	}
	if ver < version.RPCVersion11 || remoteEP == nil {
		// We do not return AuthenticationResult for old versions due to a channel binding bug.
		return cipher, nil, nil
	}

	authr := AuthenticationResult{
		Version:        ver,
		RemoteEndpoint: remoteEP,
		SessionKeys: SessionKeys{
			LocalPublic:  *pk,
			LocalPrivate: *sk,
		},
		LocalBlessings:  lBlessings,
		RemoteBlessings: rBlessings,
		LocalDischarges: lDischarges,
	}
	return cipher, &authr, nil
}

// makeSetup constructs the options that this process can support.
func makeSetup(versions *iversion.Range, localEP naming.Endpoint) (setup *message.Setup, publicKey, privateKey *crypto.BoxKey, err error) {
	publicKey, privateKey, err = crypto.GenerateBoxKey()
	if err != nil {
		return nil, nil, nil, err
	}
	options := []message.SetupOption{&message.NaclBox{PublicKey: *publicKey}}
	if localEP != nil {
		options = append(options, &message.PeerEndpoint{LocalEndpoint: localEP})
	}
	setup = &message.Setup{Versions: *versions, Options: options}
	return
}

// getDischargeClient returns the dischargeClient needed to fetch server discharges for this call.
// TODO(suharshs): Perhaps we should pass dischargeClient explicitly?
func getDischargeClient(lopts []stream.ListenerOpt) vc.DischargeClient {
	for _, o := range lopts {
		switch v := o.(type) {
		case vc.DischargeClient:
			return v
		}
	}
	return nil
}
