// 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 crypto

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"fmt"

	"golang.org/x/crypto/nacl/box"

	"v.io/v23/verror"
	"v.io/x/ref/profiles/internal/lib/iobuf"
	"v.io/x/ref/profiles/internal/rpc/stream"
)

const pkgPath = "v.io/x/ref/profiles/internal/rpc/stream/crypto"

func reg(id, msg string) verror.IDAction {
	return verror.Register(verror.ID(pkgPath+id), verror.NoRetry, msg)
}

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.
	errCipherTextTooShort     = reg(".errCipherTextTooShort", "ciphertext too short")
	errRemotePublicKey        = reg(".errRemotePublicKey", "failed to get remote public key")
	errMessageAuthFailed      = reg(".errMessageAuthFailed", "message authentication failed")
	errUnrecognizedCipherText = reg(".errUnrecognizedCipherText", "CipherSuite {3} is not recognized. Must use one that uses Diffie-Hellman as the key exchange algorithm")
)

type boxcrypter struct {
	alloc                 *iobuf.Allocator
	sharedKey             [32]byte
	sortedPubkeys         []byte
	writeNonce, readNonce uint64
}

type BoxKey [32]byte

// BoxKeyExchanger is used to communicate public keys between the two ends of
// communication.
type BoxKeyExchanger func(myPublicKey *BoxKey) (theirPublicKey *BoxKey, err error)

// NewBoxCrypter uses Curve25519, XSalsa20 and Poly1305 to encrypt and
// authenticate messages (as defined in http://nacl.cr.yp.to/box.html).
// An ephemeral Diffie-Hellman key exchange is performed per invocation
// of NewBoxCrypter; the data sent has forward security with connection
// granularity. One round-trip is required before any data can be sent.
// BoxCrypter does NOT do anything to verify the identity of the peer.
func NewBoxCrypter(exchange BoxKeyExchanger, pool *iobuf.Pool) (Crypter, error) {
	pk, sk, err := box.GenerateKey(rand.Reader)
	if err != nil {
		return nil, err
	}

	theirPK, err := exchange((*BoxKey)(pk))
	if err != nil {
		return nil, err
	}
	if theirPK == nil {
		return nil, verror.New(errRemotePublicKey, nil)
	}

	ret := &boxcrypter{alloc: iobuf.NewAllocator(pool, 0)}

	box.Precompute(&ret.sharedKey, (*[32]byte)(theirPK), sk)
	// Distinct messages between the same {sender, receiver} set are required
	// to have distinct nonces. The server with the lexicographically smaller
	// public key will be sending messages with 0, 2, 4... and the other will
	// be using 1, 3, 5...
	if bytes.Compare(pk[:], theirPK[:]) < 0 {
		ret.writeNonce, ret.readNonce = 0, 1
		ret.sortedPubkeys = append(pk[:], theirPK[:]...)
	} else {
		ret.writeNonce, ret.readNonce = 1, 0
		ret.sortedPubkeys = append(theirPK[:], pk[:]...)
	}
	return ret, nil
}

func (c *boxcrypter) Encrypt(src *iobuf.Slice) (*iobuf.Slice, error) {
	defer src.Release()
	var nonce [24]byte
	binary.LittleEndian.PutUint64(nonce[:], c.writeNonce)
	c.writeNonce += 2
	ret := c.alloc.Alloc(uint(len(src.Contents) + box.Overhead))
	ret.Contents = box.SealAfterPrecomputation(ret.Contents[:0], src.Contents, &nonce, &c.sharedKey)
	return ret, nil
}

func (c *boxcrypter) Decrypt(src *iobuf.Slice) (*iobuf.Slice, error) {
	defer src.Release()
	var nonce [24]byte
	binary.LittleEndian.PutUint64(nonce[:], c.readNonce)
	c.readNonce += 2
	retLen := len(src.Contents) - box.Overhead
	if retLen < 0 {
		return nil, verror.New(stream.ErrNetwork, nil, verror.New(errCipherTextTooShort, nil))
	}
	ret := c.alloc.Alloc(uint(retLen))
	var ok bool
	ret.Contents, ok = box.OpenAfterPrecomputation(ret.Contents[:0], src.Contents, &nonce, &c.sharedKey)
	if !ok {
		return nil, verror.New(stream.ErrSecurity, nil, verror.New(errMessageAuthFailed, nil))
	}
	return ret, nil
}

func (c *boxcrypter) ChannelBinding() []byte {
	return c.sortedPubkeys
}

func (c *boxcrypter) String() string {
	return fmt.Sprintf("%#v", *c)
}
