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

import (
	"crypto/ed25519"
	"crypto/rand"
	"errors"
	"strings"
	"testing"
	"testing/iotest"
)

func TestNewVerifier(t *testing.T) {
	vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
	_, err := NewVerifier(vkey)
	if err != nil {
		t.Fatal(err)
	}

	// Check various manglings are not accepted.
	badKey := func(k string) {
		_, err := NewVerifier(k)
		if err == nil {
			t.Errorf("NewVerifier(%q) succeeded, should have failed", k)
		}
	}

	b := []byte(vkey)
	for i := 0; i <= len(b); i++ {
		for j := i + 1; j <= len(b); j++ {
			if i != 0 || j != len(b) {
				badKey(string(b[i:j]))
			}
		}
	}
	for i := 0; i < len(b); i++ {
		b[i]++
		badKey(string(b))
		b[i]--
	}

	badKey("PeterNeumann+cc469956+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TWBADKEY==") // wrong length key, with adjusted key hash
	badKey("PeterNeumann+173116ae+ZRpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW")         // unknown algorithm, with adjusted key hash
}

func TestNewSigner(t *testing.T) {
	skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
	_, err := NewSigner(skey)
	if err != nil {
		t.Fatal(err)
	}

	// Check various manglings are not accepted.
	b := []byte(skey)
	for i := 0; i <= len(b); i++ {
		for j := i + 1; j <= len(b); j++ {
			if i == 0 && j == len(b) {
				continue
			}
			_, err := NewSigner(string(b[i:j]))
			if err == nil {
				t.Errorf("NewSigner(%q) succeeded, should have failed", b[i:j])
			}
		}
	}
	for i := 0; i < len(b); i++ {
		b[i]++
		_, err := NewSigner(string(b))
		if err == nil {
			t.Errorf("NewSigner(%q) succeeded, should have failed", b)
		}
		b[i]--
	}
}

func testSignerAndVerifier(t *testing.T, Name string, signer Signer, verifier Verifier) {
	if name := signer.Name(); name != Name {
		t.Errorf("signer.Name() = %q, want %q", name, Name)
	}
	if name := verifier.Name(); name != Name {
		t.Errorf("verifier.Name() = %q, want %q", name, Name)
	}
	shash := signer.KeyHash()
	vhash := verifier.KeyHash()
	if shash != vhash {
		t.Errorf("signer.KeyHash() = %#08x != verifier.KeyHash() = %#08x", shash, vhash)
	}

	msg := []byte("hi")
	sig, err := signer.Sign(msg)
	if err != nil {
		t.Fatalf("signer.Sign: %v", err)
	}
	if !verifier.Verify(msg, sig) {
		t.Fatalf("verifier.Verify failed on signature returned by signer.Sign")
	}
	sig[0]++
	if verifier.Verify(msg, sig) {
		t.Fatalf("verifier.Verify succeeded on corrupt signature")
	}
	sig[0]--
	msg[0]++
	if verifier.Verify(msg, sig) {
		t.Fatalf("verifier.Verify succeeded on corrupt message")
	}
}

func TestGenerateKey(t *testing.T) {
	// Generate key pair, make sure it is all self-consistent.
	const Name = "EnochRoot"

	skey, vkey, err := GenerateKey(rand.Reader, Name)
	if err != nil {
		t.Fatalf("GenerateKey: %v", err)
	}
	signer, err := NewSigner(skey)
	if err != nil {
		t.Fatalf("NewSigner: %v", err)
	}
	verifier, err := NewVerifier(vkey)
	if err != nil {
		t.Fatalf("NewVerifier: %v", err)
	}

	testSignerAndVerifier(t, Name, signer, verifier)

	// Check that GenerateKey returns error from rand reader.
	_, _, err = GenerateKey(iotest.TimeoutReader(iotest.OneByteReader(rand.Reader)), Name)
	if err == nil {
		t.Fatalf("GenerateKey succeeded with error-returning rand reader")
	}
}

func TestFromEd25519(t *testing.T) {
	const Name = "EnochRoot"

	pub, priv, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		t.Fatalf("GenerateKey: %v", err)
	}
	signer, err := newSignerFromEd25519Seed(Name, priv.Seed())
	if err != nil {
		t.Fatalf("newSignerFromEd25519Seed: %v", err)
	}
	vkey, err := NewEd25519VerifierKey(Name, pub)
	if err != nil {
		t.Fatalf("NewEd25519VerifierKey: %v", err)
	}
	verifier, err := NewVerifier(vkey)
	if err != nil {
		t.Fatalf("NewVerifier: %v", err)
	}

	testSignerAndVerifier(t, Name, signer, verifier)

	// Check that wrong key sizes return errors.
	_, err = NewEd25519VerifierKey(Name, pub[:len(pub)-1])
	if err == nil {
		t.Errorf("NewEd25519VerifierKey succeeded with a seed of the wrong size")
	}
}

// newSignerFromEd25519Seed constructs a new signer from a verifier name and a
// crypto/ed25519 private key seed.
func newSignerFromEd25519Seed(name string, seed []byte) (Signer, error) {
	if len(seed) != ed25519.SeedSize {
		return nil, errors.New("invalid seed size")
	}
	priv := ed25519.NewKeyFromSeed(seed)
	pub := priv[32:]

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

	s := &signer{
		name: name,
		hash: hash,
		sign: func(msg []byte) ([]byte, error) {
			return ed25519.Sign(priv, msg), nil
		},
	}
	return s, nil
}

func TestSign(t *testing.T) {
	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 := NewSigner(skey)
	if err != nil {
		t.Fatal(err)
	}

	msg, err := Sign(&Note{Text: text}, signer)
	if err != nil {
		t.Fatal(err)
	}

	want := `If you think cryptography is the answer to your problem,
then you don't know what your problem is.

— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
`
	if string(msg) != want {
		t.Errorf("Sign: wrong output\nhave:\n%s\nwant:\n%s", msg, want)
	}

	// Check that existing signature is replaced by new one.
	msg, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "PeterNeumann", Hash: 0xc74f20a3, Base64: "BADSIGN="}}}, signer)
	if err != nil {
		t.Fatal(err)
	}
	if string(msg) != want {
		t.Errorf("Sign replacing signature: wrong output\nhave:\n%s\nwant:\n%s", msg, want)
	}

	// Check various bad inputs.
	_, err = Sign(&Note{Text: "abc"}, signer)
	if err == nil || err.Error() != "malformed note" {
		t.Fatalf("Sign with short text: %v, want malformed note error", err)
	}

	_, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "a+b", Base64: "ABCD"}}})
	if err == nil || err.Error() != "malformed note" {
		t.Fatalf("Sign with bad name: %v, want malformed note error", err)
	}

	_, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "PeterNeumann", Hash: 0xc74f20a3, Base64: "BADHASH="}}})
	if err == nil || err.Error() != "malformed note" {
		t.Fatalf("Sign with bad pre-filled signature: %v, want malformed note error", err)
	}

	_, err = Sign(&Note{Text: text}, &badSigner{signer})
	if err == nil || err.Error() != "invalid signer" {
		t.Fatalf("Sign with bad signer: %v, want invalid signer error", err)
	}

	_, err = Sign(&Note{Text: text}, &errSigner{signer})
	if err != errSurprise {
		t.Fatalf("Sign with failing signer: %v, want errSurprise", err)
	}
}

func TestVerifierList(t *testing.T) {
	peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
	peterVerifier, err := NewVerifier(peterKey)
	if err != nil {
		t.Fatal(err)
	}

	enochKey := "EnochRoot+af0cfe78+ATtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop"
	enochVerifier, err := NewVerifier(enochKey)
	if err != nil {
		t.Fatal(err)
	}

	list := VerifierList(peterVerifier, enochVerifier, enochVerifier)
	v, err := list.Verifier("PeterNeumann", 0xc74f20a3)
	if v != peterVerifier || err != nil {
		t.Fatalf("list.Verifier(peter) = %v, %v, want %v, nil", v, err, peterVerifier)
	}
	v, err = list.Verifier("PeterNeumann", 0xc74f20a4)
	if v != nil || err == nil || err.Error() != "unknown key PeterNeumann+c74f20a4" {
		t.Fatalf("list.Verifier(peter bad hash) = %v, %v, want nil, unknown key error", v, err)
	}

	v, err = list.Verifier("PeterNeuman", 0xc74f20a3)
	if v != nil || err == nil || err.Error() != "unknown key PeterNeuman+c74f20a3" {
		t.Fatalf("list.Verifier(peter bad name) = %v, %v, want nil, unknown key error", v, err)
	}
	v, err = list.Verifier("EnochRoot", 0xaf0cfe78)
	if v != nil || err == nil || err.Error() != "ambiguous key EnochRoot+af0cfe78" {
		t.Fatalf("list.Verifier(enoch) = %v, %v, want nil, ambiguous key error", v, err)
	}
}

type badSigner struct {
	Signer
}

func (b *badSigner) Name() string {
	return "bad name"
}

var errSurprise = errors.New("surprise!")

type errSigner struct {
	Signer
}

func (e *errSigner) Sign([]byte) ([]byte, error) {
	return nil, errSurprise
}

type fixedVerifier struct{ v Verifier }

func (v fixedVerifier) Verifier(name string, hash uint32) (Verifier, error) {
	return v.v, nil
}

func TestOpen(t *testing.T) {
	peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
	peterVerifier, err := NewVerifier(peterKey)
	if err != nil {
		t.Fatal(err)
	}

	enochKey := "EnochRoot+af0cfe78+ATtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop"
	enochVerifier, err := NewVerifier(enochKey)
	if err != nil {
		t.Fatal(err)
	}

	text := `If you think cryptography is the answer to your problem,
then you don't know what your problem is.
`
	peterSig := "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n"
	enochSig := "— EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=\n"

	peter := Signature{"PeterNeumann", 0xc74f20a3, "x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM="}
	enoch := Signature{"EnochRoot", 0xaf0cfe78, "rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ="}

	// Check one signature verified, one not.
	n, err := Open([]byte(text+"\n"+peterSig+enochSig), VerifierList(peterVerifier))
	if err != nil {
		t.Fatal(err)
	}
	if n.Text != text {
		t.Errorf("n.Text = %q, want %q", n.Text, text)
	}
	if len(n.Sigs) != 1 || n.Sigs[0] != peter {
		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter})
	}
	if len(n.UnverifiedSigs) != 1 || n.UnverifiedSigs[0] != enoch {
		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter})
	}

	// Check both verified.
	n, err = Open([]byte(text+"\n"+peterSig+enochSig), VerifierList(peterVerifier, enochVerifier))
	if err != nil {
		t.Fatal(err)
	}
	if len(n.Sigs) != 2 || n.Sigs[0] != peter || n.Sigs[1] != enoch {
		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter, enoch})
	}
	if len(n.UnverifiedSigs) != 0 {
		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{})
	}

	// Check both unverified.
	n, err = Open([]byte(text+"\n"+peterSig+enochSig), VerifierList())
	if n != nil || err == nil {
		t.Fatalf("Open unverified = %v, %v, want nil, error", n, err)
	}
	e, ok := err.(*UnverifiedNoteError)
	if !ok {
		t.Fatalf("Open unverified: err is %T, want *UnverifiedNoteError", err)
	}
	if err.Error() != "note has no verifiable signatures" {
		t.Fatalf("Open unverified: err.Error() = %q, want %q", err.Error(), "note has no verifiable signatures")
	}

	n = e.Note
	if n == nil {
		t.Fatalf("Open unverified: missing note in UnverifiedNoteError")
	}
	if len(n.Sigs) != 0 {
		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{})
	}
	if len(n.UnverifiedSigs) != 2 || n.UnverifiedSigs[0] != peter || n.UnverifiedSigs[1] != enoch {
		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter, enoch})
	}

	// Check duplicated verifier.
	_, err = Open([]byte(text+"\n"+enochSig), VerifierList(enochVerifier, peterVerifier, enochVerifier))
	if err == nil || err.Error() != "ambiguous key EnochRoot+af0cfe78" {
		t.Fatalf("Open with duplicated verifier: err=%v, want ambiguous key", err)
	}

	// Check unused duplicated verifier.
	_, err = Open([]byte(text+"\n"+peterSig), VerifierList(enochVerifier, peterVerifier, enochVerifier))
	if err != nil {
		t.Fatal(err)
	}

	// Check too many signatures.
	n, err = Open([]byte(text+"\n"+strings.Repeat(peterSig, 101)), VerifierList(peterVerifier))
	if n != nil || err == nil || err.Error() != "malformed note" {
		t.Fatalf("Open too many verified signatures = %v, %v, want nil, malformed note error", n, err)
	}
	n, err = Open([]byte(text+"\n"+strings.Repeat(peterSig, 101)), VerifierList())
	if n != nil || err == nil || err.Error() != "malformed note" {
		t.Fatalf("Open too many verified signatures = %v, %v, want nil, malformed note error", n, err)
	}

	// Invalid signature.
	n, err = Open([]byte(text+"\n"+peterSig[:60]+"ABCD"+peterSig[60:]), VerifierList(peterVerifier))
	if n != nil || err == nil || err.Error() != "invalid signature for key PeterNeumann+c74f20a3" {
		t.Fatalf("Open too many verified signatures = %v, %v, want nil, invalid signature error", n, err)
	}

	// Duplicated verified and unverified signatures.
	enochABCD := Signature{"EnochRoot", 0xaf0cfe78, "rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n" + "ABCD" + "2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ="}
	n, err = Open([]byte(text+"\n"+peterSig+peterSig+enochSig+enochSig+enochSig[:60]+"ABCD"+enochSig[60:]), VerifierList(peterVerifier))
	if err != nil {
		t.Fatal(err)
	}
	if len(n.Sigs) != 1 || n.Sigs[0] != peter {
		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter})
	}
	if len(n.UnverifiedSigs) != 2 || n.UnverifiedSigs[0] != enoch || n.UnverifiedSigs[1] != enochABCD {
		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.UnverifiedSigs, []Signature{enoch, enochABCD})
	}

	// Invalid encoded message syntax.
	badMsgs := []string{
		text,
		text + "\n",
		text + "\n" + peterSig[:len(peterSig)-1],
		"\x01" + text + "\n" + peterSig,
		"\xff" + text + "\n" + peterSig,
		text + "\n" + "— Bad Name x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=",
		text + "\n" + peterSig + "Unexpected line.\n",
	}
	for _, msg := range badMsgs {
		n, err := Open([]byte(msg), VerifierList(peterVerifier))
		if n != nil || err == nil || err.Error() != "malformed note" {
			t.Fatalf("Open bad msg = %v, %v, want nil, malformed note error\nmsg:\n%s", n, err, msg)
		}
	}

	// Verifiers returns a Verifier for the wrong name or hash.
	misnamedSig := strings.Replace(peterSig, "PeterNeumann", "CarmenSandiego", -1)
	_, err = Open([]byte(text+"\n"+misnamedSig), fixedVerifier{peterVerifier})
	if err != errMismatchedVerifier {
		t.Fatalf("Open with wrong Verifier, err=%v, want errMismatchedVerifier", err)
	}
	wrongHash := strings.Replace(peterSig, "x08g", "xxxx", -1)
	_, err = Open([]byte(text+"\n"+wrongHash), fixedVerifier{peterVerifier})
	if err != errMismatchedVerifier {
		t.Fatalf("Open with wrong Verifier, err=%v, want errMismatchedVerifier", err)
	}
}

func BenchmarkOpen(b *testing.B) {
	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 := NewVerifier(vkey)
	if err != nil {
		b.Fatal(err)
	}
	verifiers := VerifierList(verifier)
	verifiers0 := VerifierList()

	// Try with 0 signatures and 1 signature so we can tell how much each signature adds.

	b.Run("Sig0", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			_, err := Open(msg, verifiers0)
			e, ok := err.(*UnverifiedNoteError)
			if !ok {
				b.Fatal("expected UnverifiedNoteError")
			}
			n := e.Note
			if len(n.Sigs) != 0 || len(n.UnverifiedSigs) != 1 {
				b.Fatal("wrong signature count")
			}
		}
	})

	b.Run("Sig1", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			n, err := Open(msg, verifiers)
			if err != nil {
				b.Fatal(err)
			}
			if len(n.Sigs) != 1 || len(n.UnverifiedSigs) != 0 {
				b.Fatal("wrong signature count")
			}
		}
	})
}
