// Copyright 2019 The Go 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 note defines the notes signed by the Go module database server.
//
// A note is text signed by one or more server keys.
// The text should be ignored unless the note is signed by
// a trusted server key and the signature has been verified
// using the server's public key.
//
// A server's public key is identified by a name, typically the "host[/path]"
// giving the base URL of the server's transparency log.
// The syntactic restrictions on a name are that it be non-empty,
// well-formed UTF-8 containing neither Unicode spaces nor plus (U+002B).
//
// A Go module database server signs texts using public key cryptography.
// A given server may have multiple public keys, each
// identified by the first 32 bits of the SHA-256 hash of
// the concatenation of the server name, a newline, and
// the encoded public key.
//
// Verifying Notes
//
// A Verifier allows verification of signatures by one server public key.
// It can report the name of the server and the uint32 hash of the key,
// and it can verify a purported signature by that key.
//
// The standard implementation of a Verifier is constructed
// by NewVerifier starting from a verifier key, which is a
// plain text string of the form "<name>+<hash>+<keydata>".
//
// A Verifiers allows looking up a Verifier by the combination
// of server name and key hash.
//
// The standard implementation of a Verifiers is constructed
// by VerifierList from a list of known verifiers.
//
// A Note represents a text with one or more signatures.
// An implementation can reject a note with too many signatures
// (for example, more than 100 signatures).
//
// A Signature represents a signature on a note, verified or not.
//
// The Open function takes as input a signed message
// and a set of known verifiers. It decodes and verifies
// the message signatures and returns a Note structure
// containing the message text and (verified or unverified) signatures.
//
// Signing Notes
//
// A Signer allows signing a text with a given key.
// It can report the name of the server and the hash of the key
// and can sign a raw text using that key.
//
// The standard implementation of a Signer is constructed
// by NewSigner starting from an encoded signer key, which is a
// plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
// Anyone with an encoded signer key can sign messages using that key,
// so it must be kept secret. The encoding begins with the literal text
// "PRIVATE+KEY" to avoid confusion with the public server key.
//
// The Sign function takes as input a Note and a list of Signers
// and returns an encoded, signed message.
//
// Signed Note Format
//
// A signed note consists of a text ending in newline (U+000A),
// followed by a blank line (only a newline),
// followed by one or more signature lines of this form:
// em dash (U+2014), space (U+0020),
// server name, space, base64-encoded signature, newline.
//
// Signed notes must be valid UTF-8 and must not contain any
// ASCII control characters (those below U+0020) other than newline.
//
// A signature is a base64 encoding of 4+n bytes.
//
// The first four bytes in the signature are the uint32 key hash
// stored in big-endian order, which is to say they are the first
// four bytes of the truncated SHA-256 used to derive the key hash
// in the first place.
//
// The remaining n bytes are the result of using the specified key
// to sign the note text (including the final newline but not the
// separating blank line).
//
// Generating Keys
//
// There is only one key type, Ed25519 with algorithm identifier 1.
// New key types may be introduced in the future as needed,
// although doing so will require deploying the new algorithms to all clients
// before starting to depend on them for signatures.
//
// The GenerateKey function generates and returns a new signer
// and corresponding verifier.
//
// Example
//
// Here is a well-formed signed note:
//
//	If you think cryptography is the answer to your problem,
//	then you don't know what your problem is.
//
//	— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
//
// It can be constructed and displayed using:
//
//	skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
//	text := "If you think cryptography is the answer to your problem,\n" +
//		"then you don't know what your problem is.\n"
//
//	signer, err := note.NewSigner(skey)
//	if err != nil {
//		log.Fatal(err)
//	}
//
//	msg, err := note.Sign(&note.Note{Text: text}, signer)
//	if err != nil {
//		log.Fatal(err)
//	}
//	os.Stdout.Write(msg)
//
// The note's text is two lines, including the final newline,
// and the text is purportedly signed by a server named
// "PeterNeumann". (Although server names are canonically
// base URLs, the only syntactic requirement is that they
// not contain spaces or newlines).
//
// If Open is given access to a Verifiers including the
// Verifier for this key, then it will succeed at verifiying
// the encoded message and returning the parsed Note:
//
//	vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
//	msg := []byte("If you think cryptography is the answer to your problem,\n" +
//		"then you don't know what your problem is.\n" +
//		"\n" +
//		"— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n")
//
//	verifier, err := note.NewVerifier(vkey)
//	if err != nil {
//		log.Fatal(err)
//	}
//	verifiers := note.VerifierList(verifier)
//
//	n, err := note.Open([]byte(msg), verifiers)
//	if err != nil {
//		log.Fatal(err)
//	}
//	fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text)
//
// You can add your own signature to this message by re-signing the note:
//
//	skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot")
//	if err != nil {
//		log.Fatal(err)
//	}
//	_ = vkey // give to verifiers
//
//	me, err := note.NewSigner(skey)
//	if err != nil {
//		log.Fatal(err)
//	}
//
//	msg, err := note.Sign(n, me)
//	if err != nil {
//		log.Fatal(err)
//	}
//	os.Stdout.Write(msg)
//
// This will print a doubly-signed message, like:
//
//	If you think cryptography is the answer to your problem,
//	then you don't know what your problem is.
//
//	— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
//	— EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=
//
package note

import (
	"bytes"
	"crypto/sha256"
	"encoding/base64"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/crypto/ed25519"
)

// A Verifier verifies messages signed with a specific key.
type Verifier interface {
	// Name returns the server name associated with the key.
	Name() string

	// KeyHash returns the key hash.
	KeyHash() uint32

	// Verify reports whether sig is a valid signature of msg.
	Verify(msg, sig []byte) bool
}

// A Signer signs messages using a specific key.
type Signer interface {
	// Name returns the server name associated with the key.
	Name() string

	// KeyHash returns the key hash.
	KeyHash() uint32

	// Sign returns a signature for the given message.
	Sign(msg []byte) ([]byte, error)
}

// keyHash computes the key hash for the given server name and encoded public key.
func keyHash(name string, key []byte) uint32 {
	h := sha256.New()
	h.Write([]byte(name))
	h.Write([]byte("\n"))
	h.Write(key)
	sum := h.Sum(nil)
	return binary.BigEndian.Uint32(sum)
}

var (
	errVerifierID   = errors.New("malformed verifier id")
	errVerifierAlg  = errors.New("unknown verifier algorithm")
	errVerifierHash = errors.New("invalid verifier hash")
)

const (
	algEd25519 = 1
)

// isValidName reports whether name is valid.
// It must be non-empty and not have any Unicode spaces or pluses.
func isValidName(name string) bool {
	return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
}

// NewVerifier construct a new Verifier from an encoded verifier key.
func NewVerifier(vkey string) (Verifier, error) {
	name, vkey := chop(vkey, "+")
	hash16, key64 := chop(vkey, "+")
	hash, err1 := strconv.ParseUint(hash16, 16, 32)
	key, err2 := base64.StdEncoding.DecodeString(key64)
	if len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
		return nil, errVerifierID
	}
	if uint32(hash) != keyHash(name, key) {
		return nil, errVerifierHash
	}

	v := &verifier{
		name: name,
		hash: uint32(hash),
	}

	alg, key := key[0], key[1:]
	switch alg {
	default:
		return nil, errVerifierAlg

	case algEd25519:
		if len(key) != 32 {
			return nil, errVerifierID
		}
		v.verify = func(msg, sig []byte) bool {
			return ed25519.Verify(key, msg, sig)
		}
	}

	return v, nil
}

// chop chops s at the first instance of sep, if any,
// and returns the text before and after sep.
// If sep is not present, chop returns before is s and after is empty.
func chop(s, sep string) (before, after string) {
	i := strings.Index(s, sep)
	if i < 0 {
		return s, ""
	}
	return s[:i], s[i+len(sep):]
}

// verifier is a trivial Verifier implementation.
type verifier struct {
	name   string
	hash   uint32
	verify func([]byte, []byte) bool
}

func (v *verifier) Name() string                { return v.name }
func (v *verifier) KeyHash() uint32             { return v.hash }
func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }

// NewSigner constructs a new Signer from an encoded signer key.
func NewSigner(skey string) (Signer, error) {
	priv1, skey := chop(skey, "+")
	priv2, skey := chop(skey, "+")
	name, skey := chop(skey, "+")
	hash16, key64 := chop(skey, "+")
	hash, err1 := strconv.ParseUint(hash16, 16, 32)
	key, err2 := base64.StdEncoding.DecodeString(key64)
	if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
		return nil, errSignerID
	}

	// Note: hash is the hash of the public key and we have the private key.
	// Must verify hash after deriving public key.

	s := &signer{
		name: name,
		hash: uint32(hash),
	}

	var pubkey []byte

	alg, key := key[0], key[1:]
	switch alg {
	default:
		return nil, errSignerAlg

	case algEd25519:
		if len(key) != 32 {
			return nil, errSignerID
		}
		key = ed25519.NewKeyFromSeed(key)
		pubkey = append([]byte{algEd25519}, key[32:]...)
		s.sign = func(msg []byte) ([]byte, error) {
			return ed25519.Sign(key, msg), nil
		}
	}

	if uint32(hash) != keyHash(name, pubkey) {
		return nil, errSignerHash
	}

	return s, nil
}

var (
	errSignerID   = errors.New("malformed verifier id")
	errSignerAlg  = errors.New("unknown verifier algorithm")
	errSignerHash = errors.New("invalid verifier hash")
)

// signer is a trivial Signer implementation.
type signer struct {
	name string
	hash uint32
	sign func([]byte) ([]byte, error)
}

func (s *signer) Name() string                    { return s.name }
func (s *signer) KeyHash() uint32                 { return s.hash }
func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) }

// GenerateKey generates a signer and verifier key pair for a named server.
// The signer key skey is private and must be kept secret.
func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) {
	pub, priv, err := ed25519.GenerateKey(rand)
	if err != nil {
		return "", "", err
	}
	pubkey := append([]byte{algEd25519}, pub...)
	privkey := append([]byte{algEd25519}, priv.Seed()...)
	h := keyHash(name, pubkey)

	skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey))
	vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey))
	return skey, vkey, nil
}

// NewEd25519VerifierKey returns an encoded verifier key using the given name
// and Ed25519 public key.
func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) {
	if len(key) != ed25519.PublicKeySize {
		return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize)
	}

	pubkey := append([]byte{algEd25519}, key...)
	hash := keyHash(name, pubkey)

	b64Key := base64.StdEncoding.EncodeToString(pubkey)
	return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil
}

// A Verifiers is a collection of known verifier keys.
type Verifiers interface {
	// Verifier returns the Verifier associated with the key
	// identified by the name and hash.
	// If the name, hash pair is unknown, Verifier should return
	// an UnknownVerifierError.
	Verifier(name string, hash uint32) (Verifier, error)
}

// An UnknownVerifierError indicates that the given key is not known.
// The Open function records signatures without associated verifiers as
// unverified signatures.
type UnknownVerifierError struct {
	Name    string
	KeyHash uint32
}

func (e *UnknownVerifierError) Error() string {
	return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash)
}

// An ambiguousVerifierError indicates that the given name and hash
// match multiple keys passed to VerifierList.
// (If this happens, some malicious actor has taken control of the
// verifier list, at which point we may as well give up entirely,
// but we diagnose the problem instead.)
type ambiguousVerifierError struct {
	name string
	hash uint32
}

func (e *ambiguousVerifierError) Error() string {
	return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
}

// VerifierList returns a Verifiers implementation that uses the given list of verifiers.
func VerifierList(list ...Verifier) Verifiers {
	m := make(verifierMap)
	for _, v := range list {
		k := nameHash{v.Name(), v.KeyHash()}
		m[k] = append(m[k], v)
	}
	return m
}

type nameHash struct {
	name string
	hash uint32
}

type verifierMap map[nameHash][]Verifier

func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) {
	v, ok := m[nameHash{name, hash}]
	if !ok {
		return nil, &UnknownVerifierError{name, hash}
	}
	if len(v) > 1 {
		return nil, &ambiguousVerifierError{name, hash}
	}
	return v[0], nil
}

// A Note is a text and signatures.
type Note struct {
	Text           string      // text of note
	Sigs           []Signature // verified signatures
	UnverifiedSigs []Signature // unverified signatures
}

// A Signature is a single signature found in a note.
type Signature struct {
	// Name and Hash give the name and key hash
	// for the key that generated the signature.
	Name string
	Hash uint32

	// Base64 records the base64-encoded signature bytes.
	Base64 string
}

// An UnverifiedNoteError indicates that the note
// successfully parsed but had no verifiable signatures.
type UnverifiedNoteError struct {
	Note *Note
}

func (e *UnverifiedNoteError) Error() string {
	return "note has no verifiable signatures"
}

// An InvalidSignatureError indicates that the given key was known
// and the associated Verifier rejected the signature.
type InvalidSignatureError struct {
	Name string
	Hash uint32
}

func (e *InvalidSignatureError) Error() string {
	return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash)
}

var (
	errMalformedNote = errors.New("malformed note")
	errInvalidSigner = errors.New("invalid signer")

	sigSplit  = []byte("\n\n")
	sigPrefix = []byte("— ")
)

// Open opens and parses the message msg, checking signatures from the known verifiers.
//
// For each signature in the message, Open calls known.Verifier to find a verifier.
// If known.Verifier returns a verifier and the verifier accepts the signature,
// Open records the signature in the returned note's Sigs field.
// If known.Verifier returns a verifier but the verifier rejects the signature,
// Open returns an InvalidSignatureError.
// If known.Verifier returns an UnknownVerifierError,
// Open records the signature in the returned note's UnverifiedSigs field.
// If known.Verifier returns any other error, Open returns that error.
//
// If no known verifier has signed an otherwise valid note,
// Open returns an UnverifiedNoteError.
// In this case, the unverified note can be fetched from inside the error.
func Open(msg []byte, known Verifiers) (*Note, error) {
	if known == nil {
		// Treat nil Verifiers as empty list, to produce useful error instead of crash.
		known = VerifierList()
	}

	// Must have valid UTF-8 with no non-newline ASCII control characters.
	for i := 0; i < len(msg); {
		r, size := utf8.DecodeRune(msg[i:])
		if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 {
			return nil, errMalformedNote
		}
		i += size
	}

	// Must end with signature block preceded by blank line.
	split := bytes.LastIndex(msg, sigSplit)
	if split < 0 {
		return nil, errMalformedNote
	}
	text, sigs := msg[:split+1], msg[split+2:]
	if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' {
		return nil, errMalformedNote
	}

	n := &Note{
		Text: string(text),
	}

	// Parse and verify signatures.
	// Ignore duplicate signatures.
	seen := make(map[nameHash]bool)
	seenUnverified := make(map[string]bool)
	numSig := 0
	for len(sigs) > 0 {
		// Pull out next signature line.
		// We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one.
		i := bytes.IndexByte(sigs, '\n')
		line := sigs[:i]
		sigs = sigs[i+1:]

		if !bytes.HasPrefix(line, sigPrefix) {
			return nil, errMalformedNote
		}
		line = line[len(sigPrefix):]
		name, b64 := chop(string(line), " ")
		sig, err := base64.StdEncoding.DecodeString(b64)
		if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 {
			return nil, errMalformedNote
		}
		hash := binary.BigEndian.Uint32(sig[0:4])
		sig = sig[4:]

		if numSig++; numSig > 100 {
			// Avoid spending forever parsing a note with many signatures.
			return nil, errMalformedNote
		}

		v, err := known.Verifier(name, hash)
		if _, ok := err.(*UnknownVerifierError); ok {
			// Drop repeated identical unverified signatures.
			if seenUnverified[string(line)] {
				continue
			}
			seenUnverified[string(line)] = true
			n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64})
			continue
		}
		if err != nil {
			return nil, err
		}

		// Drop repeated signatures by a single verifier.
		if seen[nameHash{name, hash}] {
			continue
		}
		seen[nameHash{name, hash}] = true

		ok := v.Verify(text, sig)
		if !ok {
			return nil, &InvalidSignatureError{name, hash}
		}

		n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64})
	}

	// Parsed and verified all the signatures.
	if len(n.Sigs) == 0 {
		return nil, &UnverifiedNoteError{n}
	}
	return n, nil
}

// Sign signs the note with the given signers and returns the encoded message.
// The new signatures from signers are listed in the encoded message after
// the existing signatures already present in n.Sigs.
// If any signer uses the same key as an existing signature,
// the existing signature is elided from the output.
func Sign(n *Note, signers ...Signer) ([]byte, error) {
	var buf bytes.Buffer
	if !strings.HasSuffix(n.Text, "\n") {
		return nil, errMalformedNote
	}
	buf.WriteString(n.Text)

	// Prepare signatures.
	var sigs bytes.Buffer
	have := make(map[nameHash]bool)
	for _, s := range signers {
		name := s.Name()
		hash := s.KeyHash()
		have[nameHash{name, hash}] = true
		if !isValidName(name) {
			return nil, errInvalidSigner
		}

		sig, err := s.Sign(buf.Bytes()) // buf holds n.Text
		if err != nil {
			return nil, err
		}

		var hbuf [4]byte
		binary.BigEndian.PutUint32(hbuf[:], hash)
		b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...))
		sigs.WriteString("— ")
		sigs.WriteString(name)
		sigs.WriteString(" ")
		sigs.WriteString(b64)
		sigs.WriteString("\n")
	}

	buf.WriteString("\n")

	// Emit existing signatures not replaced by new ones.
	for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} {
		for _, sig := range list {
			name, hash := sig.Name, sig.Hash
			if !isValidName(name) {
				return nil, errMalformedNote
			}
			if have[nameHash{name, hash}] {
				continue
			}
			// Double-check hash against base64.
			raw, err := base64.StdEncoding.DecodeString(sig.Base64)
			if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash {
				return nil, errMalformedNote
			}
			buf.WriteString("— ")
			buf.WriteString(sig.Name)
			buf.WriteString(" ")
			buf.WriteString(sig.Base64)
			buf.WriteString("\n")
		}
	}
	buf.Write(sigs.Bytes())

	return buf.Bytes(), nil
}
