// Copyright 2013 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 rsa

import (
	"bufio"
	"bytes"
	"compress/bzip2"
	"crypto"
	_ "crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	_ "crypto/sha256"
	"encoding/hex"
	"math/big"
	"os"
	"strconv"
	"strings"
	"testing"
)

func TestEMSAPSS(t *testing.T) {
	// Test vector in file pss-int.txt from: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
	msg := []byte{
		0x85, 0x9e, 0xef, 0x2f, 0xd7, 0x8a, 0xca, 0x00, 0x30, 0x8b,
		0xdc, 0x47, 0x11, 0x93, 0xbf, 0x55, 0xbf, 0x9d, 0x78, 0xdb,
		0x8f, 0x8a, 0x67, 0x2b, 0x48, 0x46, 0x34, 0xf3, 0xc9, 0xc2,
		0x6e, 0x64, 0x78, 0xae, 0x10, 0x26, 0x0f, 0xe0, 0xdd, 0x8c,
		0x08, 0x2e, 0x53, 0xa5, 0x29, 0x3a, 0xf2, 0x17, 0x3c, 0xd5,
		0x0c, 0x6d, 0x5d, 0x35, 0x4f, 0xeb, 0xf7, 0x8b, 0x26, 0x02,
		0x1c, 0x25, 0xc0, 0x27, 0x12, 0xe7, 0x8c, 0xd4, 0x69, 0x4c,
		0x9f, 0x46, 0x97, 0x77, 0xe4, 0x51, 0xe7, 0xf8, 0xe9, 0xe0,
		0x4c, 0xd3, 0x73, 0x9c, 0x6b, 0xbf, 0xed, 0xae, 0x48, 0x7f,
		0xb5, 0x56, 0x44, 0xe9, 0xca, 0x74, 0xff, 0x77, 0xa5, 0x3c,
		0xb7, 0x29, 0x80, 0x2f, 0x6e, 0xd4, 0xa5, 0xff, 0xa8, 0xba,
		0x15, 0x98, 0x90, 0xfc,
	}
	salt := []byte{
		0xe3, 0xb5, 0xd5, 0xd0, 0x02, 0xc1, 0xbc, 0xe5, 0x0c, 0x2b,
		0x65, 0xef, 0x88, 0xa1, 0x88, 0xd8, 0x3b, 0xce, 0x7e, 0x61,
	}
	expected := []byte{
		0x66, 0xe4, 0x67, 0x2e, 0x83, 0x6a, 0xd1, 0x21, 0xba, 0x24,
		0x4b, 0xed, 0x65, 0x76, 0xb8, 0x67, 0xd9, 0xa4, 0x47, 0xc2,
		0x8a, 0x6e, 0x66, 0xa5, 0xb8, 0x7d, 0xee, 0x7f, 0xbc, 0x7e,
		0x65, 0xaf, 0x50, 0x57, 0xf8, 0x6f, 0xae, 0x89, 0x84, 0xd9,
		0xba, 0x7f, 0x96, 0x9a, 0xd6, 0xfe, 0x02, 0xa4, 0xd7, 0x5f,
		0x74, 0x45, 0xfe, 0xfd, 0xd8, 0x5b, 0x6d, 0x3a, 0x47, 0x7c,
		0x28, 0xd2, 0x4b, 0xa1, 0xe3, 0x75, 0x6f, 0x79, 0x2d, 0xd1,
		0xdc, 0xe8, 0xca, 0x94, 0x44, 0x0e, 0xcb, 0x52, 0x79, 0xec,
		0xd3, 0x18, 0x3a, 0x31, 0x1f, 0xc8, 0x96, 0xda, 0x1c, 0xb3,
		0x93, 0x11, 0xaf, 0x37, 0xea, 0x4a, 0x75, 0xe2, 0x4b, 0xdb,
		0xfd, 0x5c, 0x1d, 0xa0, 0xde, 0x7c, 0xec, 0xdf, 0x1a, 0x89,
		0x6f, 0x9d, 0x8b, 0xc8, 0x16, 0xd9, 0x7c, 0xd7, 0xa2, 0xc4,
		0x3b, 0xad, 0x54, 0x6f, 0xbe, 0x8c, 0xfe, 0xbc,
	}

	hash := sha1.New()
	hash.Write(msg)
	hashed := hash.Sum(nil)

	encoded, err := emsaPSSEncode(hashed, 1023, salt, sha1.New())
	if err != nil {
		t.Errorf("Error from emsaPSSEncode: %s\n", err)
	}
	if !bytes.Equal(encoded, expected) {
		t.Errorf("Bad encoding. got %x, want %x", encoded, expected)
	}

	if err = emsaPSSVerify(hashed, encoded, 1023, len(salt), sha1.New()); err != nil {
		t.Errorf("Bad verification: %s", err)
	}
}

// TestPSSGolden tests all the test vectors in pss-vect.txt from
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
func TestPSSGolden(t *testing.T) {
	inFile, err := os.Open("testdata/pss-vect.txt.bz2")
	if err != nil {
		t.Fatalf("Failed to open input file: %s", err)
	}
	defer inFile.Close()

	// The pss-vect.txt file contains RSA keys and then a series of
	// signatures. A goroutine is used to preprocess the input by merging
	// lines, removing spaces in hex values and identifying the start of
	// new keys and signature blocks.
	const newKeyMarker = "START NEW KEY"
	const newSignatureMarker = "START NEW SIGNATURE"

	values := make(chan string)

	go func() {
		defer close(values)
		scanner := bufio.NewScanner(bzip2.NewReader(inFile))
		var partialValue string
		lastWasValue := true

		for scanner.Scan() {
			line := scanner.Text()
			switch {
			case len(line) == 0:
				if len(partialValue) > 0 {
					values <- strings.ReplaceAll(partialValue, " ", "")
					partialValue = ""
					lastWasValue = true
				}
				continue
			case strings.HasPrefix(line, "# ======") && lastWasValue:
				values <- newKeyMarker
				lastWasValue = false
			case strings.HasPrefix(line, "# ------") && lastWasValue:
				values <- newSignatureMarker
				lastWasValue = false
			case strings.HasPrefix(line, "#"):
				continue
			default:
				partialValue += line
			}
		}
		if err := scanner.Err(); err != nil {
			panic(err)
		}
	}()

	var key *PublicKey
	var hashed []byte
	hash := crypto.SHA1
	h := hash.New()
	opts := &PSSOptions{
		SaltLength: PSSSaltLengthEqualsHash,
	}

	for marker := range values {
		switch marker {
		case newKeyMarker:
			key = new(PublicKey)
			nHex, ok := <-values
			if !ok {
				continue
			}
			key.N = bigFromHex(nHex)
			key.E = intFromHex(<-values)
			// We don't care for d, p, q, dP, dQ or qInv.
			for i := 0; i < 6; i++ {
				<-values
			}
		case newSignatureMarker:
			msg := fromHex(<-values)
			<-values // skip salt
			sig := fromHex(<-values)

			h.Reset()
			h.Write(msg)
			hashed = h.Sum(hashed[:0])

			if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil {
				t.Error(err)
			}
		default:
			t.Fatalf("unknown marker: " + marker)
		}
	}
}

// TestPSSOpenSSL ensures that we can verify a PSS signature from OpenSSL with
// the default options. OpenSSL sets the salt length to be maximal.
func TestPSSOpenSSL(t *testing.T) {
	hash := crypto.SHA256
	h := hash.New()
	h.Write([]byte("testing"))
	hashed := h.Sum(nil)

	// Generated with `echo -n testing | openssl dgst -sign key.pem -sigopt rsa_padding_mode:pss -sha256 > sig`
	sig := []byte{
		0x95, 0x59, 0x6f, 0xd3, 0x10, 0xa2, 0xe7, 0xa2, 0x92, 0x9d,
		0x4a, 0x07, 0x2e, 0x2b, 0x27, 0xcc, 0x06, 0xc2, 0x87, 0x2c,
		0x52, 0xf0, 0x4a, 0xcc, 0x05, 0x94, 0xf2, 0xc3, 0x2e, 0x20,
		0xd7, 0x3e, 0x66, 0x62, 0xb5, 0x95, 0x2b, 0xa3, 0x93, 0x9a,
		0x66, 0x64, 0x25, 0xe0, 0x74, 0x66, 0x8c, 0x3e, 0x92, 0xeb,
		0xc6, 0xe6, 0xc0, 0x44, 0xf3, 0xb4, 0xb4, 0x2e, 0x8c, 0x66,
		0x0a, 0x37, 0x9c, 0x69,
	}

	if err := VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, nil); err != nil {
		t.Error(err)
	}
}

func TestPSSNilOpts(t *testing.T) {
	hash := crypto.SHA256
	h := hash.New()
	h.Write([]byte("testing"))
	hashed := h.Sum(nil)

	SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, nil)
}

func TestPSSSigning(t *testing.T) {
	var saltLengthCombinations = []struct {
		signSaltLength, verifySaltLength int
		good                             bool
	}{
		{PSSSaltLengthAuto, PSSSaltLengthAuto, true},
		{PSSSaltLengthEqualsHash, PSSSaltLengthAuto, true},
		{PSSSaltLengthEqualsHash, PSSSaltLengthEqualsHash, true},
		{PSSSaltLengthEqualsHash, 8, false},
		{PSSSaltLengthAuto, PSSSaltLengthEqualsHash, false},
		{8, 8, true},
	}

	hash := crypto.MD5
	h := hash.New()
	h.Write([]byte("testing"))
	hashed := h.Sum(nil)
	var opts PSSOptions

	for i, test := range saltLengthCombinations {
		opts.SaltLength = test.signSaltLength
		sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts)
		if err != nil {
			t.Errorf("#%d: error while signing: %s", i, err)
			continue
		}

		opts.SaltLength = test.verifySaltLength
		err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts)
		if (err == nil) != test.good {
			t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err)
		}
	}
}

func bigFromHex(hex string) *big.Int {
	n, ok := new(big.Int).SetString(hex, 16)
	if !ok {
		panic("bad hex: " + hex)
	}
	return n
}

func intFromHex(hex string) int {
	i, err := strconv.ParseInt(hex, 16, 32)
	if err != nil {
		panic(err)
	}
	return int(i)
}

func fromHex(hexStr string) []byte {
	s, err := hex.DecodeString(hexStr)
	if err != nil {
		panic(err)
	}
	return s
}
