// 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 bcrypter defines the mechanisms for blessings based
// encryption and decryption.
package bcrypter

import (
	"crypto/sha256"
	"fmt"
	"strings"
	"sync"

	"v.io/v23/context"
	"v.io/v23/security"

	"v.io/x/lib/ibe"
)

type crypterKey struct{}

const hashTruncation = 16

// Crypter provides operations for encrypting and decrypting messages for
// principals with specific blessings.
//
// In particular, it offers a mechanism to encrypt a message for a specific
// blessing pattern so that it can only be decrypted by crypters that possess
// a private key for a blessing matched by that pattern. Such a private key
// is generated by the identity provider that granted the blessing.
type Crypter struct {
	mu sync.RWMutex
	// root blessing -> []ibe.Params
	params map[string][]ibe.Params
	// paramsId -> patternId -> ibe.PrivateKey
	keys map[string]map[string]ibe.PrivateKey
}

// Ciphertext represents the ciphertext generated by a Crypter.
type Ciphertext struct {
	wire WireCiphertext
}

// Root represents an identity provider for the purposes of blessings based
// encryption and decryption.
//
// It generates private keys for specific blessings which can be used
// to decrypt any message encrypted for a pattern matched by the blessing (
// assuming the encryption used this identity provider's parameters).
type Root struct {
	// master is the IBE Master that this root uses to extract IBE
	// private keys.
	master ibe.Master
	// blessing is the blessing name of the identity provider. The identity
	// provider  can extract private keys for blessings that are extensions
	// of this blessing name.
	blessing string
}

// Params represents the public parameters of an identity provider (aka Root).
type Params struct {
	// blessing is the blessing name of the identity provider.
	blessing string
	// params are the public IBE params of the identity provider
	params ibe.Params
}

// PrivateKey represent the private key corresponding to a blessing.
//
// The private key can be used for decrypting any message encrypted using
// a pattern matched by the blessing (assuming the private key and encryption
// used the same identity provider parameters).
type PrivateKey struct {
	// blessing is the blessing for which this private key was extracted for.
	blessing string
	// params represents the public parameters of the identity provider
	// that extracted this private key. The blessing must be an extension
	// of params.blessing.
	params Params
	// keys contain private keys extracted for each blessing pattern that is
	// matched by the blessing and is an extension of root.blessing.
	//
	// For example, if the blessing is "google:u:alice:phone" and root.blessing
	// is "google:u" then the keys are extracted for patterns "google:u",
	// "google:u:alice", "google:u:alice:phone", and "google:u:alice:phone:$".
	//
	// The private keys are listed in increasing order of the lengths of the
	// corresponding patterns.
	keys []ibe.PrivateKey
}

// Encrypt encrypts the provided 'plaintext' so that it can only be decrypted
// by a crypter possessing a private key for a blessing matching the provided
// blessing pattern.
//
// Encryption makes use of the public parameters of the identity provider
// that is authoritative on the set of blessings that match the provided
// blessing pattern. These paramaters must have been previously added to
// this crypter via AddParams.
func (c *Crypter) Encrypt(ctx *context.T, forPattern security.BlessingPattern, plaintext []byte) (*Ciphertext, error) {
	if !forPattern.IsValid() {
		return nil, fmt.Errorf("provided blessing pattern %v is invalid", forPattern)
	}
	ciphertext := &Ciphertext{wire: WireCiphertext{PatternId: idPattern(forPattern), Bytes: make(map[string][]byte)}}
	paramsFound := false
	c.mu.RLock()
	defer c.mu.RUnlock()
	for name, ibeParamsList := range c.params {
		if !isExtensionOf(forPattern, name) {
			continue
		}
		for _, ibeParams := range ibeParamsList {
			ctxt := make([]byte, len(plaintext)+ibeParams.CiphertextOverhead())
			if err := ibeParams.Encrypt(string(forPattern), plaintext, ctxt); err != nil {
				return nil, NewErrInternal(ctx, err)
			}
			paramsId, err := idParams(ibeParams)
			if err != nil {
				return nil, NewErrInternal(ctx, err)
			}
			paramsFound = true
			ciphertext.wire.Bytes[paramsId] = ctxt
		}
	}
	if !paramsFound {
		return nil, NewErrNoParams(ctx, forPattern)
	}
	return ciphertext, nil
}

func decrypt(key ibe.PrivateKey, ciphertext []byte) ([]byte, error) {
	overhead := key.Params().CiphertextOverhead()
	if got := len(ciphertext); got < overhead {
		return nil, fmt.Errorf("ciphertext is of size %v bytes, want at least %v bytes", got, overhead)
	}
	plaintext := make([]byte, len(ciphertext)-overhead)
	if err := key.Decrypt(ciphertext, plaintext); err != nil {
		return nil, err
	}
	return plaintext, nil
}

// Decrypt decrypts the provided 'ciphertext' and returns the corresponding
// plaintext.
//
// Decryption succeeds only if this crypter possesses a private key for a
// blessing that matches the blessing pattern corresponding to the ciphertext.
func (c *Crypter) Decrypt(ctx *context.T, ciphertext *Ciphertext) ([]byte, error) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	for paramsId, cbytes := range ciphertext.wire.Bytes {
		if keys, found := c.keys[paramsId]; !found {
			continue
		} else if key, found := keys[ciphertext.wire.PatternId]; !found {
			continue
		} else if ptxt, err := decrypt(key, cbytes); err != nil {
			return nil, err
		} else {
			return ptxt, nil
		}
	}
	return nil, NewErrPrivateKeyNotFound(ctx)
}

// AddKey adds the provided private key 'key' and the associated public
// parameters (key.Params()) to this crypter.
func (c *Crypter) AddKey(ctx *context.T, key *PrivateKey) error {
	patterns := matchedBy(key.blessing, key.params.blessing)
	if got, want := len(key.keys), len(patterns); got != want {
		return NewErrInvalidPrivateKey(ctx, fmt.Errorf("got %d IBE private keys for blessing %v (and root blessing %v), expected %d", got, key.blessing, key.params.blessing, want))
	}

	paramsId, err := idParams(key.params.params)
	if err != nil {
		return NewErrInternal(ctx, err)
	}

	c.mu.Lock()
	defer c.mu.Unlock()
	c.params[key.params.blessing] = append(c.params[key.params.blessing], key.params.params)
	if _, found := c.keys[paramsId]; !found {
		c.keys[paramsId] = make(map[string]ibe.PrivateKey)
	}
	for i, p := range patterns {
		c.keys[paramsId][idPattern(p)] = key.keys[i]
	}
	return nil
}

// AddParams adds the provided identity provider parameters to this crypter.
//
// The added parameters would be used to encrypt plaintexts for blessing patterns
// that the identity provider is authoritative on.
func (c *Crypter) AddParams(ctx *context.T, params Params) error {
	c.mu.RLock()
	defer c.mu.RUnlock()
	// TODO(ataly, ashankar): Avoid adding duplicate params to the list.
	c.params[params.blessing] = append(c.params[params.blessing], params.params)
	return nil
}

// Blessing returns the blessing that this private key was extracted for.
func (k *PrivateKey) Blessing() string {
	return k.blessing
}

// Params returns the public parameters of the identity provider that
// extracted this private key.
func (k *PrivateKey) Params() Params {
	return k.params
}

// Params returns the public parameters of the identity provider represented
// by 'r'.
func (r *Root) Params() Params {
	return Params{blessing: r.blessing, params: r.master.Params()}
}

// Extract returns a private key for the provided blessing.
//
// The private key can be used for decrypting any message encrypted using a
// pattern matched by the blessing (assuming the encryption made use of the
// public parameters of this root).
func (r *Root) Extract(ctx *context.T, blessing string) (*PrivateKey, error) {
	patterns := matchedBy(blessing, r.blessing)
	if len(patterns) == 0 {
		return nil, fmt.Errorf("blessing %v does not match the blessing pattern this root is authoritative on: %v", blessing, r.blessing)
	}
	key := &PrivateKey{
		blessing: blessing,
		params:   r.Params(),
		keys:     make([]ibe.PrivateKey, len(patterns)),
	}
	for i, p := range patterns {
		ibeKey, err := r.master.Extract(string(p))
		if err != nil {
			return nil, NewErrInternal(ctx, err)
		}
		key.keys[i] = ibeKey
	}
	return key, nil
}

// Blessing returns the blessing name of the identity provider with
// public parameters 'p'.
func (p *Params) Blessing() string {
	return p.blessing
}

// NewCrypter returns a new Crypter with an empty set of private keys
// and identity provider parameters.
func NewCrypter() *Crypter {
	return &Crypter{params: make(map[string][]ibe.Params), keys: make(map[string]map[string]ibe.PrivateKey)}
}

// WithCrypter derives a new context from the provided one by attaching
// the provided crypter to it.
func WithCrypter(ctx *context.T, crypter *Crypter) *context.T {
	return context.WithValue(ctx, crypterKey{}, crypter)
}

// GetCrypter returns the crypter attached to the context, or nil if no
// crypter is attached.
func GetCrypter(ctx *context.T) *Crypter {
	crypter, _ := ctx.Value(crypterKey{}).(*Crypter)
	return crypter
}

// NewRoot returns a new root identity provider that has the provided
// blessing name and uses the provided 'master' for setting up identity-based
// encryption.
func NewRoot(blessing string, master ibe.Master) *Root {
	return &Root{blessing: blessing, master: master}
}

// matchedBy returns the set of blessing patterns (in increasing order
// of length) that are matched by the provided 'blessing' and are equal
// to or extensions of the blessing name 'root'.
func matchedBy(blessing, root string) []security.BlessingPattern {
	if !security.BlessingPattern(root).MatchedBy(blessing) {
		return nil
	}
	patterns := make([]security.BlessingPattern, strings.Count(blessing, security.ChainSeparator)+2-strings.Count(string(root), security.ChainSeparator))
	patterns[len(patterns)-1] = security.BlessingPattern(blessing).MakeNonExtendable()
	patterns[len(patterns)-2] = security.BlessingPattern(blessing)
	for idx := len(patterns) - 3; idx >= 0; idx-- {
		blessing = blessing[0:strings.LastIndex(blessing, string(security.ChainSeparator))]
		patterns[idx] = security.BlessingPattern(blessing)
	}
	return patterns
}

// idPattern returns a 128-bit truncated SHA-256 hash of a blessing pattern.
func idPattern(pattern security.BlessingPattern) string {
	h := sha256.Sum256([]byte(pattern))
	truncated := h[:hashTruncation]
	return string(truncated)
}

// idParams returns a 128-bit truncated SHA-256 hash of the marshaled IBE params.
func idParams(params ibe.Params) (string, error) {
	paramsBytes, err := ibe.MarshalParams(params)
	if err != nil {
		return "", err
	}
	h := sha256.Sum256(paramsBytes)
	truncated := h[:hashTruncation]
	return string(truncated), nil
}

// isExtensionOf returns true if the all blessings matching the provided
// 'pattern' are an extension of the provided 'root' blessing
func isExtensionOf(pattern security.BlessingPattern, root string) bool {
	return string(pattern) == root || strings.HasPrefix(string(pattern), root+security.ChainSeparator)
}
