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

import (
	"bytes"
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
	"time"

	"v.io/v23/context"
	"v.io/v23/verror"
)

var (
	errEmptyChain         = verror.Register(pkgPath+".errEmptyChain", verror.NoRetry, "empty certificate chain in blessings")
	errMisconfiguredRoots = verror.Register(pkgPath+".errMisconfiguredRoots", verror.NoRetry, "recognized root certificates not configured")
	errMultiplePublicKeys = verror.Register(pkgPath+".errMultiplePublicKeys", verror.NoRetry, "invalid blessings: two certificate chains that bind to different public keys")
	errInvalidUnion       = verror.Register(pkgPath+".errInvalidUnion", verror.NoRetry, "cannot create union of blessings bound to different public keys")
	errNeedRoots          = verror.Register(pkgPath+".errNeedRoots", verror.NoRetry, "{1:}{2:}principal does not have any BlessingRoots{:_}")
	errCantAddRoot        = verror.Register(pkgPath+".errCantAddRoot", verror.NoRetry, "{1:}{2:}failed to Add root: {3} for pattern: {4} to this principal's roots: {5}{:_}")
)

// Blessings encapsulates all cryptographic operations required to
// prove that a set of (human-readable) blessing names are bound
// to a principal in a specific call.
//
// Blessings objects are meant to be presented to other principals to
// authenticate and authorize actions. The functions 'LocalBlessingNames',
// 'SigningBlessingNames' and 'RemoteBlessingNames' defined in this package
// can be used to uncover the blessing names encapsulated in these objects.
//
// Blessings objects are immutable and multiple goroutines may invoke methods
// on them simultaneously.
//
// See also: https://vanadium.github.io/glossary.html#blessing
type Blessings struct {
	chains    [][]Certificate
	publicKey PublicKey
	digests   [][]byte // digests[i] is the digest of chains[i]
	uniqueID  []byte
}

// PublicKey returns the public key of the principal to which
// blessings obtained from this object are bound.
//
// Can return nil if b is the zero value.
func (b Blessings) PublicKey() PublicKey { return b.publicKey }

// ThirdPartyCaveats returns the set of third-party restrictions on the
// scope of the blessings (i.e., the subset of Caveats for which
// ThirdPartyDetails will be non-nil).
func (b Blessings) ThirdPartyCaveats() []Caveat {
	var ret []Caveat
	for _, chain := range b.chains {
		for _, cert := range chain {
			for _, cav := range cert.Caveats {
				if tp := cav.ThirdPartyDetails(); tp != nil {
					ret = append(ret, cav)
				}
			}
		}
	}
	return ret
}

// IsZero returns true if b represents the zero value of blessings (an empty
// set).
func (b Blessings) IsZero() bool {
	// b.publicKey == nil <=> len(b.chains) == 0
	return b.publicKey == nil
}

// Equivalent returns true if 'b' and 'blessings' can be used interchangeably,
// i.e., 'b' will be authorized wherever 'blessings' is and vice-versa.
func (b Blessings) Equivalent(blessings Blessings) bool {
	return bytes.Equal(b.UniqueID(), blessings.UniqueID())
}

// UniqueID returns an identifier of the set of blessings. Two blessings
// objects with the same UniqueID are interchangeable for any authorization
// decisions.
//
// The converse is not guaranteed at this time. Two interchangeable blessings
// objects may in theory have different UniqueIDs.
func (b Blessings) UniqueID() []byte { return b.uniqueID }

func (b *Blessings) init() {
	if len(b.digests) == 0 {
		return
	}
	tohash := make([]byte, 0, len(b.digests[0])*len(b.digests))
	for _, d := range b.digests {
		tohash = append(tohash, d...)
	}
	b.uniqueID = b.publicKey.hash().sum(tohash)
}

// CouldHaveNames returns true iff the blessings 'b' encapsulates the provided
// set of blessing names.
//
// This check ignores all caveats on the blessing name and the recognition status
// of its blessing root.
func (b Blessings) CouldHaveNames(names []string) bool {
	hasNames := make(map[string]bool)
	for _, chain := range b.chains {
		hasNames[claimedName(chain)] = true
	}
	for _, n := range names {
		if !hasNames[n] {
			return false
		}
	}
	return true
}

// Expiry returns the time at which b will no longer be valid, or the zero
// value of time.Time if the blessing does not expire.
func (b Blessings) Expiry() time.Time {
	var min time.Time
	for _, chain := range b.chains {
		for _, cert := range chain {
			for _, cav := range cert.Caveats {
				if t := expiryTime(cav); !t.IsZero() && (min.IsZero() || t.Before(min)) {
					min = t
				}
			}
		}
	}
	return min
}

func (b Blessings) publicKeyDER() []byte {
	chain := b.chains[0]
	return chain[len(chain)-1].PublicKey
}

func (b Blessings) String() string {
	blessings := make([]string, len(b.chains))
	for chainidx, chain := range b.chains {
		onechain := make([]string, len(chain))
		for certidx, cert := range chain {
			onechain[certidx] = cert.Extension
		}
		blessings[chainidx] = fmt.Sprintf("%v", strings.Join(onechain, ChainSeparator))
	}
	return strings.Join(blessings, ",")
}

// We keep a pool of buffers for claimedName, this saves a lot of allocations.
var claimedPool = sync.Pool{New: func() interface{} {
	return &bytes.Buffer{}
}}

// claimedName returns the blessing name that the certificate chain claims to
// have (i.e., ignoring any caveats or recognition of the root public key as an
// authority on the namespace).
func claimedName(chain []Certificate) string {
	buf := claimedPool.Get().(*bytes.Buffer)
	buf.Reset()
	buf.WriteString(chain[0].Extension)
	for i := 1; i < len(chain); i++ {
		buf.WriteString(ChainSeparator)
		buf.WriteString(chain[i].Extension)
	}
	ret := buf.String()
	claimedPool.Put(buf)
	return ret
}

func nameForPrincipal(pubkey []byte, roots BlessingRoots, chain []Certificate) string {
	// Verify the chain belongs to this principal
	if !bytes.Equal(chain[len(chain)-1].PublicKey, pubkey) {
		return ""
	}
	// Verify that the root of the chain is recognized as an authority on
	// blessing.
	blessing := claimedName(chain)
	if err := roots.Recognized(chain[0].PublicKey, blessing); err != nil {
		return ""
	}
	return blessing
}

// chainCaveats returns the union of the set of caveats in the  certificates present
// in 'chain'.
func chainCaveats(chain []Certificate) []Caveat {
	var cavs []Caveat
	for _, c := range chain {
		cavs = append(cavs, c.Caveats...)
	}
	return cavs
}

func defaultCaveatValidation(ctx *context.T, call Call, chains [][]Caveat) []error {
	results := make([]error, len(chains))
	for i, chain := range chains {
		for _, cav := range chain {
			if err := cav.Validate(ctx, call); err != nil {
				results[i] = err
				break
			}
		}
	}
	return results
}

// TODO(ashankar): Get rid of this function? It allows users to mess
// with the integrity of 'b'.
func MarshalBlessings(b Blessings) WireBlessings {
	return WireBlessings{b.chains}
}

func WireBlessingsToNative(wire WireBlessings, native *Blessings) error {
	if len(wire.CertificateChains) == 0 {
		return nil
	}
	certchains := wire.CertificateChains
	if len(certchains) == 0 || len(certchains[0]) == 0 {
		return verror.New(errEmptyChain, nil)
	}
	// if this is a nameless blessing
	if isNamelessChains(certchains) {
		cert := certchains[0][0]
		pk, err := UnmarshalPublicKey(cert.PublicKey)
		if err != nil {
			return err
		}
		digest, _ := cert.chainedDigests(pk.hash(), nil)
		*native = Blessings{
			chains:    [][]Certificate{{cert}},
			publicKey: pk,
			digests:   [][]byte{digest},
		}
		native.init()
		return nil
	}
	// Public keys should match for all chains.
	marshaledkey := certchains[0][len(certchains[0])-1].PublicKey
	digests := make([][]byte, len(certchains))

	var key PublicKey
	var err error
	if key, digests[0], err = validateCertificateChain(certchains[0]); err != nil {
		return err
	}
	for i := 1; i < len(certchains); i++ {
		chain := certchains[i]
		if len(chain) == 0 {
			return verror.New(errEmptyChain, nil)
		}
		cert := chain[len(chain)-1]
		if !bytes.Equal(marshaledkey, cert.PublicKey) {
			return verror.New(errMultiplePublicKeys, nil)
		}
		if _, digests[i], err = validateCertificateChain(chain); err != nil {
			return err
		}
	}
	native.chains = certchains
	native.publicKey = key
	native.digests = digests
	native.init()
	return nil
}

func WireBlessingsFromNative(wire *WireBlessings, native Blessings) error {
	wire.CertificateChains = native.chains
	return nil
}

// UnionOfBlessings returns a Blessings object that carries the union of the
// provided blessings.
//
// All provided Blessings must have the same PublicKey.
//
// UnionOfBlessings with no arguments returns (nil, nil).
func UnionOfBlessings(blessings ...Blessings) (Blessings, error) {
	for len(blessings) > 0 && blessings[0].IsZero() {
		blessings = blessings[1:]
	}
	switch len(blessings) {
	case 0:
		return Blessings{}, nil
	case 1:
		return blessings[0], nil
	}
	key0 := blessings[0].publicKeyDER()
	onlyNameless := blessings[0].isNamelessBlessing()
	var ret Blessings
	for idx, b := range blessings {
		if b.IsZero() || b.isNamelessBlessing() {
			continue
		}
		onlyNameless = false
		if idx > 0 && !bytes.Equal(key0, b.publicKeyDER()) {
			return Blessings{}, verror.New(errInvalidUnion, nil)
		}
		ret.chains = append(ret.chains, b.chains...)
		ret.digests = append(ret.digests, b.digests...)
	}
	if onlyNameless {
		return blessings[0], nil
	}
	var err error
	if ret.publicKey, err = UnmarshalPublicKey(key0); err != nil {
		return Blessings{}, err
	}
	// For pretty printing, sort the certificate chains so that there is a consistent
	// ordering, irrespective of the ordering of arguments to UnionOfBlessings.
	sort.Stable(blessingsSorter(ret))
	ret.init()
	return ret, nil
}

type blessingsSorter Blessings

func (b blessingsSorter) Len() int { return len(b.chains) }
func (b blessingsSorter) Swap(i, j int) {
	b.chains[i], b.chains[j] = b.chains[j], b.chains[i]
	b.digests[i], b.digests[j] = b.digests[j], b.digests[i]
}
func (b blessingsSorter) Less(i, j int) bool {
	ci := b.chains[i]
	cj := b.chains[j]
	if len(ci) < len(cj) {
		return true
	}
	if len(ci) > len(cj) {
		return false
	}
	// Equal size chains, order by the names in the certificates.
	N := len(ci)
	for idx := 0; idx < N; idx++ {
		ie := ci[idx].Extension
		je := cj[idx].Extension
		if ie < je {
			return true
		}
		if ie > je {
			return false
		}
	}
	return false
}

func (i RejectedBlessing) String() string {
	return fmt.Sprintf("{%q: %v}", i.Blessing, i.Err)
}

// DefaultBlessingPatterns returns the BlessingsPatterns of the Default Blessings
// of the provided Principal.
func DefaultBlessingPatterns(p Principal) (patterns []BlessingPattern) {
	blessings, _ := p.BlessingStore().Default()
	for _, b := range BlessingNames(p, blessings) {
		patterns = append(patterns, BlessingPattern(b))
	}
	return
}

var (
	caveatValidationMu         sync.RWMutex
	caveatValidation           = defaultCaveatValidation
	caveatValidationOverridden = false
)

func overrideCaveatValidation(fn func(ctx *context.T, call Call, sets [][]Caveat) []error) {
	caveatValidationMu.Lock()
	if caveatValidationOverridden {
		panic("security: OverrideCaveatValidation may only be called once")
	}
	caveatValidationOverridden = true
	caveatValidation = fn
	caveatValidationMu.Unlock()
}

func setCaveatValidationForTest(fn func(ctx *context.T, call Call, sets [][]Caveat) []error) {
	// For tests we skip the panic on multiple calls, so that we can easily revert
	// to the default validator.
	caveatValidationMu.Lock()
	caveatValidation = fn
	caveatValidationMu.Unlock()
}

func getCaveatValidation() func(ctx *context.T, call Call, sets [][]Caveat) []error {
	caveatValidationMu.RLock()
	fn := caveatValidation
	caveatValidationMu.RUnlock()
	return fn
}

func isSigningBlessingCaveat(cav Caveat) bool {
	switch cav.Id {
	case ExpiryCaveat.Id:
		return true
	case ConstCaveat.Id:
		return true
	}
	// TODO(ataly): Figure out what revocation caveats can be supported
	// for signing blessings. Our current revocation caveats are third-party
	// caveats and are unsuitable for signing for the following reasons:
	// - They violate the requirement that the caveat should be universally
	//   understandable and validatable. This is because validating the
	//   caveat requires reaching out to a third-party caveat discharger
	//   which may be reachable from some services and unreachable from others
	//   (perhaps due to network partitions).
	// - Given a third-party caveat, there is no way to tell whether it is revocation
	//   caveat.
	return false
}

func validateCaveatsForSigning(ctx *context.T, call Call, chain []Certificate) error {
	for _, cav := range chainCaveats(chain) {
		if !isSigningBlessingCaveat(cav) {
			return NewErrInvalidSigningBlessingCaveat(nil, cav.Id)
		}
		if err := cav.Validate(ctx, call); err != nil {
			return err
		}
	}
	return nil
}

// RootBlessings returns the blessings of the roots of b.
// In other words, RootBlessings returns the blessings of the identity
// providers encapsulated in b.
//
// In particular:
//     AddToRoots(p, b)
// is equivalent to:
//     for _, root := range RootBlessings(b) {
//         AddToRoots(p, root)
//     }
// Why would you use the latter? Only to share roots with another process,
// without revealing your complete blessings and using fewer bytes.
func RootBlessings(b Blessings) []Blessings {
	if b.isNamelessBlessing() {
		return nil
	}
	ret := make([]Blessings, len(b.chains))
	for i, chain := range b.chains {
		// One option is to convert to WireBlessings and back.
		// But that involves a lot of crypto verification that has
		// already been done, so why bother.
		if len(chain) == 0 {
			continue
		}
		var (
			cert      = chain[0]
			digest, _ = cert.chainedDigests(cert.Signature.Hash, nil)
			ptr       = &ret[i]
		)
		ptr.chains = [][]Certificate{[]Certificate{cert}}
		ptr.digests = [][]byte{digest}
		// The public key must parse because there is no way to create
		// b without a valid certificate chain.
		ptr.publicKey, _ = UnmarshalPublicKey(cert.PublicKey)
		ptr.init()
	}
	if len(ret) == 0 {
		return nil
	}
	return ret
}

// SigningBlessings returns a blessings object that encapsulates the subset of
// names of the provided blessings object that can be used to sign data at rest.
//
// The names of the returned blessings object can be obtained using the
// 'SigningNames' function.
func SigningBlessings(blessings Blessings) Blessings {
	ret := Blessings{}
	if blessings.IsZero() || blessings.isNamelessBlessing() {
		return ret
	}
	for _, chain := range blessings.chains {
		suitableForSigning := true
		for _, cav := range chainCaveats(chain) {
			if !isSigningBlessingCaveat(cav) {
				suitableForSigning = false
				break
			}
		}
		if suitableForSigning {
			ret.chains = append(ret.chains, chain)
		}
	}
	if len(ret.chains) > 0 {
		ret.publicKey = blessings.publicKey
	}
	return ret
}

// SigningBlessingNames returns the validated set of human-readable blessing
// names encapsulated in the provided signing blessings object, as determined
// by the provided principal.
//
// This function also returns the RejectedBlessings for each blessing name that
// cannot be validated.
// TODO(ataly): While the principal is encapsulated inside context.T, we can't
// extract it due to an import cycle issue. Therefore at the moment we have the
// principal separately passed to this function. We should clean this up.
func SigningBlessingNames(ctx *context.T, p Principal, blessings Blessings) ([]string, []RejectedBlessing) {
	if ctx == nil || p == nil {
		return nil, nil
	}
	if blessings.IsZero() || blessings.isNamelessBlessing() {
		return nil, nil
	}
	var (
		validatedNames []string
		rejected       []RejectedBlessing
		call           = NewCall(&CallParams{LocalPrincipal: p, RemoteBlessings: blessings})
	)
	for _, chain := range blessings.chains {
		name := claimedName(chain)
		if err := p.Roots().Recognized(chain[0].PublicKey, name); err != nil {
			rejected = append(rejected, RejectedBlessing{name, err})
			continue
		}
		if err := validateCaveatsForSigning(ctx, call, chain); err != nil {
			rejected = append(rejected, RejectedBlessing{name, err})
			continue
		}
		validatedNames = append(validatedNames, name)
	}
	return validatedNames, rejected
}

// RemoteBlessingNames returns the validated set of human-readable blessing names
// encapsulated in the blessings object presented by the remote end of a call.
//
// The blessing names are guaranteed to:
//
// (1) Satisfy all the caveats associated with them, in the context of the call.
// (2) Be rooted in call.LocalPrincipal.Roots.
//
// Caveats are considered satisfied for the 'call' if the CaveatValidator implementation
// can be found in the address space of the caller and Validate returns nil.
//
// RemoteBlessingNames also returns the RejectedBlessings for each blessing name that cannot
// be validated.
func RemoteBlessingNames(ctx *context.T, call Call) ([]string, []RejectedBlessing) {
	if ctx == nil || call == nil {
		return nil, nil
	}
	b := call.RemoteBlessings()
	if b.IsZero() || b.isNamelessBlessing() {
		return nil, nil
	}
	var (
		validatedNames    []string
		rejected          []RejectedBlessing
		pendingNames      []string
		pendingCaveatSets [][]Caveat
		rootsErr          error
	)
	if p := call.LocalPrincipal(); p == nil || p.Roots() == nil {
		// These conditions should not be possible: Here only for
		// unittests where the Call object is intentionally limited.
		rootsErr = verror.New(errMisconfiguredRoots, ctx)
	}
	for _, chain := range b.chains {
		name := claimedName(chain)
		err := rootsErr
		if err == nil {
			err = call.LocalPrincipal().Roots().Recognized(chain[0].PublicKey, name)
		}
		if err != nil {
			rejected = append(rejected, RejectedBlessing{name, err})
			continue
		}
		cavs := chainCaveats(chain)
		if len(cavs) == 0 {
			validatedNames = append(validatedNames, name) // No caveats to validate, add it to blessingNames.
		} else {
			pendingNames = append(pendingNames, name)
			pendingCaveatSets = append(pendingCaveatSets, cavs)
		}
	}
	if len(pendingCaveatSets) == 0 {
		return validatedNames, rejected
	}

	validationResults := getCaveatValidation()(ctx, call, pendingCaveatSets)
	if g, w := len(validationResults), len(pendingNames); g != w {
		panic(fmt.Sprintf("Got wrong number of validation results. Got %d, expected %d.", g, w))
	}

	for i, resultErr := range validationResults {
		if resultErr == nil {
			validatedNames = append(validatedNames, pendingNames[i])
		} else {
			rejected = append(rejected, RejectedBlessing{pendingNames[i], resultErr})
		}
	}
	return validatedNames, rejected
}

// LocalBlessingNames returns the set of human-readable blessing names
// encapsulated in the blessings object presented by the local end of the call.
//
// This is just a convenience function over:
//     BlessingNames(call.LocalPrincipal(), call.LocalBlessings())
func LocalBlessingNames(ctx *context.T, call Call) []string {
	if ctx == nil || call == nil {
		return nil
	}
	return BlessingNames(call.LocalPrincipal(), call.LocalBlessings())
}

// BlessingNames returns the set of human-readable blessing names encapsulated
// in blessings.
//
// The returned names are guaranteed to be rooted in principal.Roots, though
// caveats may not be validated.
//
// The blessings must be bound to principal. There is intentionally no API to
// obtain blessing names bound to other principals by ignoring caveats.  This
// is to prevent accidental authorization based on potentially invalid names
// (since caveats are not validated).
func BlessingNames(principal Principal, blessings Blessings) []string {
	pKey, err := principal.PublicKey().MarshalBinary()
	if err != nil {
		return nil
	}
	chains := blessings.chains
	if len(chains) == 0 {
		return nil
	}
	// Blessings objects contain multiple certificate chains all bound to
	// the same public key, so checking that any one of them is bound to
	// pKey is sufficient.
	if !bytes.Equal(chains[0][len(chains[0])-1].PublicKey, pKey) {
		return nil
	}
	var ret []string
	for _, chain := range blessings.chains {
		name := claimedName(chain)
		if err := principal.Roots().Recognized(chain[0].PublicKey, name); err == nil {
			ret = append(ret, name)
		}
	}
	return ret
}

// NamelessBlessing returns a blessings object that has no names, only the
// provided public key.
func NamelessBlessing(pk PublicKey) (Blessings, error) {
	pkbytes, err := pk.MarshalBinary()
	if err != nil {
		return Blessings{}, err
	}
	cert := Certificate{PublicKey: pkbytes}
	digest, _ := cert.chainedDigests(pk.hash(), nil)
	b := Blessings{
		chains:    [][]Certificate{{cert}},
		publicKey: pk,
		digests:   [][]byte{digest},
	}
	b.init()
	return b, nil
}

func (b Blessings) isNamelessBlessing() bool {
	return b.publicKey != nil && isNamelessChains(b.chains)
}

func isNamelessChains(chains [][]Certificate) bool {
	var emptyCert Certificate
	if len(chains) != 1 || len(chains[0]) != 1 {
		return false
	}
	cert := chains[0][0]
	cert.PublicKey = nil
	return reflect.DeepEqual(cert, emptyCert)
}

// AddToRoots marks the root principals of all blessing chains represented by
// 'blessings' as an authority on blessing chains beginning at that root name
// in p.BlessingRoots().
//
// For example, if blessings represents the blessing chains
// ["alice:friend:spouse", "charlie:family:daughter"] then AddToRoots(blessing)
// will mark the root public key of the chain "alice:friend:bob" as the
// authority on all blessings that match the pattern "alice", and root public
// key of the chain "charlie:family:daughter" as an authority on all blessings
// that match the pattern "charlie".
//
// This is a convenience function over extracting the names and public keys of
// the roots of blessings and invoking p.Roots().Add(...).
func AddToRoots(p Principal, blessings Blessings) error {
	if p.Roots() == nil {
		return verror.New(errNeedRoots, nil)
	}
	if blessings.isNamelessBlessing() {
		return nil
	}
	chains := blessings.chains
	for _, chain := range chains {
		pattern := BlessingPattern(chain[0].Extension)
		root := chain[0].PublicKey
		if err := p.Roots().Add(root, pattern); err != nil {
			return verror.New(errCantAddRoot, nil, root, pattern, err)
		}
	}
	return nil
}
