// Copyright 2017 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.

// Note: Can run these tests against the non-BoringCrypto
// version of the code by using "CGO_ENABLED=0 go test".

package rsa

import (
	"bytes"
	"crypto"
	"crypto/rand"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/asn1"
	"encoding/hex"
	"reflect"
	"runtime"
	"runtime/debug"
	"sync"
	"sync/atomic"
	"testing"
	"unsafe"
)

func TestBoringASN1Marshal(t *testing.T) {
	k, err := GenerateKey(rand.Reader, 128)
	if err != nil {
		t.Fatal(err)
	}
	// This used to fail, because of the unexported 'boring' field.
	// Now the compiler hides it [sic].
	_, err = asn1.Marshal(k.PublicKey)
	if err != nil {
		t.Fatal(err)
	}
}

func TestBoringDeepEqual(t *testing.T) {
	k, err := GenerateKey(rand.Reader, 128)
	if err != nil {
		t.Fatal(err)
	}
	k.boring = nil // probably nil already but just in case
	k2 := *k
	k2.boring = unsafe.Pointer(k) // anything not nil, for this test
	if !reflect.DeepEqual(k, &k2) {
		// compiler should be hiding the boring field from reflection
		t.Fatalf("DeepEqual compared boring fields")
	}
}

func TestBoringVerify(t *testing.T) {
	// This changed behavior and broke golang.org/x/crypto/openpgp.
	// Go accepts signatures without leading 0 padding, while BoringCrypto does not.
	// So the Go wrappers must adapt.
	key := &PublicKey{
		N: bigFromHex("c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be1"),
		E: 65537,
	}

	hash := fromHex("019c5571724fb5d0e47a4260c940e9803ba05a44")
	paddedHash := fromHex("3021300906052b0e03021a05000414019c5571724fb5d0e47a4260c940e9803ba05a44")

	// signature is one byte shorter than key.N.
	sig := fromHex("5edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56")

	err := VerifyPKCS1v15(key, 0, paddedHash, sig)
	if err != nil {
		t.Errorf("raw: %v", err)
	}

	err = VerifyPKCS1v15(key, crypto.SHA1, hash, sig)
	if err != nil {
		t.Errorf("sha1: %v", err)
	}
}

// The goal for BoringCrypto is to be indistinguishable from standard Go crypto.
// Test that when routines are passed a not-actually-random reader, they
// consume and potentially expose the expected bits from that reader.
// This is awful but it makes sure that golden tests based on deterministic
// "randomness" sources are unchanged by BoringCrypto.
//
// For decryption and signing, r is only used for blinding,
// so we can and do still use BoringCrypto with its own true
// randomness source, but we must be careful to consume
// from r as if we'd used it for blinding.

type testRandReader struct {
	t      *testing.T
	offset int64
	seq    [8]byte
	data   []byte
	buf    [32]byte
}

func (r *testRandReader) Read(b []byte) (int, error) {
	if len(r.data) == 0 && len(b) > 0 {
		for i := range r.seq {
			r.seq[i]++
			if r.seq[i] != 0 {
				break
			}
		}
		r.buf = sha256.Sum256(r.seq[:])
		r.data = r.buf[:]
	}
	n := copy(b, r.data)
	r.data = r.data[n:]
	r.offset += int64(n)
	return n, nil
}

func (r *testRandReader) checkOffset(offset int64) {
	if r.offset != offset {
		r.t.Fatalf("r.offset = %d, expected %d", r.offset, offset)
	}
}

func testRand(t *testing.T) *testRandReader {
	return &testRandReader{t: t}
}

var testKeyCache struct {
	once sync.Once
	k    *PrivateKey
}

func testKey(t *testing.T) *PrivateKey {
	testKeyCache.once.Do(func() {
		// Note: Key must be 2048 bits in order to trigger
		// BoringCrypto code paths.
		k, err := GenerateKey(testRand(t), 2048)
		if err != nil {
			t.Fatal(err)
		}
		testKeyCache.k = k
	})
	return testKeyCache.k
}

func bytesFromHex(t *testing.T, x string) []byte {
	b, err := hex.DecodeString(x)
	if err != nil {
		t.Fatal(err)
	}
	return b
}

func TestBoringRandGenerateKey(t *testing.T) {
	r := testRand(t)
	k, err := GenerateKey(r, 2048) // 2048 is smallest size BoringCrypto might kick in for
	if err != nil {
		t.Fatal(err)
	}
	n := bigFromHex("b2e9c4c8b1c0f03ba6994fe1e715a3e598f0571f4676da420615b7b997d431ea7535ceb98e6b52172fe0d2fccfc5f696d1b34144f7d19d85633fcbf56daff805a66457b360b1b0f40ec18fb83f4c9b86f1b5fe26b209cdfff26911a95047df797210969693226423915c9be53ff1c06f86fe2d228273ef25970b90a3c70979f9d68458d5dd38f6700436f7cd5939c04be3e1f2ff52272513171540a685c9e8c8e20694e529cc3e0cc13d2fb91ac499d44b920a03e42be89a15e7ca73c29f2e2a1a8a7d9be57516ccb95e878db6ce6096e386a793cccc19eba15a37cc0f1234b7a25ee7c87569bc74c7ef3d6ad8d84a5ddb1e8901ae593f945523fe5e0ed451a5")
	if k.N.Cmp(n) != 0 {
		t.Fatalf("GenerateKey: wrong N\nhave %x\nwant %x", k.N, n)
	}
	r.checkOffset(35200)

	// Non-Boring GenerateKey always sets CRTValues to a non-nil (possibly empty) slice.
	if k.Precomputed.CRTValues == nil {
		t.Fatalf("GenerateKey: Precomputed.CRTValues = nil")
	}
}

func TestBoringRandGenerateMultiPrimeKey(t *testing.T) {
	r := testRand(t)
	k, err := GenerateMultiPrimeKey(r, 2, 2048)
	if err != nil {
		t.Fatal(err)
	}
	n := bigFromHex("b2e9c4c8b1c0f03ba6994fe1e715a3e598f0571f4676da420615b7b997d431ea7535ceb98e6b52172fe0d2fccfc5f696d1b34144f7d19d85633fcbf56daff805a66457b360b1b0f40ec18fb83f4c9b86f1b5fe26b209cdfff26911a95047df797210969693226423915c9be53ff1c06f86fe2d228273ef25970b90a3c70979f9d68458d5dd38f6700436f7cd5939c04be3e1f2ff52272513171540a685c9e8c8e20694e529cc3e0cc13d2fb91ac499d44b920a03e42be89a15e7ca73c29f2e2a1a8a7d9be57516ccb95e878db6ce6096e386a793cccc19eba15a37cc0f1234b7a25ee7c87569bc74c7ef3d6ad8d84a5ddb1e8901ae593f945523fe5e0ed451a5")
	if k.N.Cmp(n) != 0 {
		t.Fatalf("GenerateKey: wrong N\nhave %x\nwant %x", k.N, n)
	}
	r.checkOffset(35200)
}

func TestBoringRandEncryptPKCS1v15(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	enc, err := EncryptPKCS1v15(r, &k.PublicKey, []byte("hello world"))
	if err != nil {
		t.Fatal(err)
	}
	want := bytesFromHex(t, "a8c8c0d248e669942a140c1184e1112afbf794b7427d9ac966bd2dbb4c05a2fee76f311f7feec743b8a8715e34bf741b0d0c4226559daf4de258ff712178e3f25fecb7d3eee90251e8ae4b4b7b907cd2763948cc9da34ce83c69934b523830545a536c1ba4d3740f4687e877acee9c768bcd8e88d472ba5d905493121f4830d95dcea36ef0f1223ffb0a9008eddfc53aca36877328924a2c631dce4b67e745564301fe51ab2c768b39e525bda1e1a08e029b58c53a0b92285f734592d2deebda957bcfd29c697aee263fce5c5023c7d3495b6a9114a8ac691aa661721cf45973b68678bb1e15d6605b9040951163d5b6df0d7f0b20dcefa251a7a8947a090f4b")
	if !bytes.Equal(enc, want) {
		t.Fatalf("EncryptPKCS1v15: wrong enc\nhave %x\nwant %x", enc, want)
	}
	r.checkOffset(242)
}

func TestBoringRandDecryptPKCS1v15(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	enc := bytesFromHex(t, "a8c8c0d248e669942a140c1184e1112afbf794b7427d9ac966bd2dbb4c05a2fee76f311f7feec743b8a8715e34bf741b0d0c4226559daf4de258ff712178e3f25fecb7d3eee90251e8ae4b4b7b907cd2763948cc9da34ce83c69934b523830545a536c1ba4d3740f4687e877acee9c768bcd8e88d472ba5d905493121f4830d95dcea36ef0f1223ffb0a9008eddfc53aca36877328924a2c631dce4b67e745564301fe51ab2c768b39e525bda1e1a08e029b58c53a0b92285f734592d2deebda957bcfd29c697aee263fce5c5023c7d3495b6a9114a8ac691aa661721cf45973b68678bb1e15d6605b9040951163d5b6df0d7f0b20dcefa251a7a8947a090f4b")
	dec, err := DecryptPKCS1v15(r, k, enc)
	if err != nil {
		t.Fatal(err)
	}
	want := []byte("hello world")
	if !bytes.Equal(dec, want) {
		t.Fatalf("DecryptPKCS1v15: wrong dec\nhave %x\nwant %x", dec, want)
	}
	r.checkOffset(256)
}

func TestBoringRandDecryptPKCS1v15SessionKey(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	enc := bytesFromHex(t, "a8c8c0d248e669942a140c1184e1112afbf794b7427d9ac966bd2dbb4c05a2fee76f311f7feec743b8a8715e34bf741b0d0c4226559daf4de258ff712178e3f25fecb7d3eee90251e8ae4b4b7b907cd2763948cc9da34ce83c69934b523830545a536c1ba4d3740f4687e877acee9c768bcd8e88d472ba5d905493121f4830d95dcea36ef0f1223ffb0a9008eddfc53aca36877328924a2c631dce4b67e745564301fe51ab2c768b39e525bda1e1a08e029b58c53a0b92285f734592d2deebda957bcfd29c697aee263fce5c5023c7d3495b6a9114a8ac691aa661721cf45973b68678bb1e15d6605b9040951163d5b6df0d7f0b20dcefa251a7a8947a090f4b")
	dec := make([]byte, 11)
	err := DecryptPKCS1v15SessionKey(r, k, enc, dec)
	if err != nil {
		t.Fatal(err)
	}
	want := []byte("hello world")
	if !bytes.Equal(dec, want) {
		t.Fatalf("DecryptPKCS1v15SessionKey: wrong dec\nhave %x\nwant %x", dec, want)
	}
	r.checkOffset(256)
}

func TestBoringRandSignPKCS1v15(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	sum := sha1.Sum([]byte("hello"))
	sig, err := SignPKCS1v15(r, k, crypto.SHA1, sum[:])
	if err != nil {
		t.Fatal(err)
	}
	want := bytesFromHex(t, "4a8da3c0c41af2b8a93d011d4e11f4da9b2d52641c6c3d78d863987e857295adcedfae0e0d3ec00352bd134dc3fbb93b23a1fbe3718775762d78165bbbd37c6ef8e07bfa44e16ed2f1b05ebc04ba7bd60162d8689edb8709349e06bc281d34c2a3ee75d3454bfd95053cbb27c10515fb9132290a6ecc858e0c003201a9e100aac7f66af967364a1176e4ed9ef672d41481c59580f98bb82f205f712153fd5e3035a811da9d6e56e50609d1d604857f6d8e958bb84f354cfa28e0b8bcbb1261f929382d431454f07cbf60c18ff1243b11c6b552f3a0aa7e936f45cded40688ee53b1b630f944139f4f51baae49cd039b57b2b82f58f5589335137f4b09bd315f5")
	if !bytes.Equal(sig, want) {
		t.Fatalf("SignPKCS1v15(hash=SHA1): wrong sig\nhave %x\nwant %x", sig, want)
	}

	sig, err = SignPKCS1v15(r, k, 0, sum[:])
	if err != nil {
		t.Fatal(err)
	}
	want = bytesFromHex(t, "5d3d34495ffade926adab2de0545aaf1f22a03def949b69e1c91d34a2f0c7f2d682af46034151a1b67aa22cb9c1a8cc24c1358fce9ac6a2141879bbe107371b14faa97b12494260d9602ed1355f22ab3495b0bb7c137bc6801c1113fc2bdc00d4c250bbd8fa17e4ff86f71544b30a78e9d62c0b949afd1159760282c2700ec8be24cd884efd585ec55b45506d90e66cc3c5911baaea961e6c4e8018c4b4feb04afdd71880e3d8eff120288e53289a1bfb9fe7a3b9aca1d4549f133063647bfd4c6f4c0f4038f1bbcb4d112aa601f1b15402595076adfdbefb1bb64d3193bafb0305145bb536cd949a03ebe0470c6a155369f784afab2e25e9d5c03d8e13dcf1a")
	if !bytes.Equal(sig, want) {
		t.Fatalf("SignPKCS1v15(hash=0): wrong sig\nhave %x\nwant %x", sig, want)
	}
	r.checkOffset(768)
}

func TestBoringRandSignPSS(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	sum := sha1.Sum([]byte("hello"))
	sig, err := SignPSS(r, k, crypto.SHA1, sum[:], nil)
	if err != nil {
		t.Fatal(err)
	}
	want := bytesFromHex(t, "a0de84c9654c2e78e33c899090f8dc0590046fda4ee29d133340800596401ae0df61bf8aa5689df3f873ad13cf55df5209c3a8c6450918b74c2017f87c2d588809740622c7752e3153a26d04bd3e9d9f6daa676e8e5e65a8a11d4fbd271d4693ab6a303652328dc1c923b484fa179fd6d9e8b523da74f3a307531c0dd75f243a041f7df22414dfdb83b3a241fe73e7af0f95cb6b60831bdd46dc05618e5cb3653476eb7d5405fa5ca98dad8f787ca86179055f305daa87eb424671878a93965e47d3002e2774be311d696b42e5691eddb2f788cd35246b408eb5d045c891ba1d57ce4c6fc935ceec90f7999406252f6266957cce4e7f12cf0ec94af358aeefa7")
	if !bytes.Equal(sig, want) {
		t.Fatalf("SignPSS: wrong sig\nhave %x\nwant %x", sig, want)
	}
	r.checkOffset(490)
}

func TestBoringRandEncryptOAEP(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	enc, err := EncryptOAEP(sha256.New(), r, &k.PublicKey, []byte("hello"), []byte("label"))
	if err != nil {
		t.Fatal(err)
	}
	want := bytesFromHex(t, "55dc7b590a511c2d249232ecbb70040e8e0ec03206caae5ec0a401a0ad8013209ef546870f93d0946b9845ace092d456d092403f76f12ee65c2b8759731a25589d8a7e857407d09cfbe36ae36fc4daeb514ac597b1de2f7dc8450ab78a9e420c9b5dbbae3e402c8f378bd35505a47d556b705ab8985707a22e3583c172ef5730f05fd0845880d67c1ddd3c1525aa4c2c4e162bd6435a485609f6bd76c8ff73a7b5d043e4724458594703245fabdb479ef2786c757b35932a645399f2703647785b59b971970e6bccef3e6cd6fae39f9f135203eb104f0db20cf48e461cb7d824889c0d5d6a47cd0bf213c2f7acb3ddbd3effefebb4f60458ffc8b6ff1e4cc447")
	if !bytes.Equal(enc, want) {
		t.Fatalf("EncryptOAEP: wrong enc\nhave %x\nwant %x", enc, want)
	}
	r.checkOffset(32)
}

func TestBoringRandDecryptOAEP(t *testing.T) {
	r := testRand(t)
	k := testKey(t)
	enc := bytesFromHex(t, "55dc7b590a511c2d249232ecbb70040e8e0ec03206caae5ec0a401a0ad8013209ef546870f93d0946b9845ace092d456d092403f76f12ee65c2b8759731a25589d8a7e857407d09cfbe36ae36fc4daeb514ac597b1de2f7dc8450ab78a9e420c9b5dbbae3e402c8f378bd35505a47d556b705ab8985707a22e3583c172ef5730f05fd0845880d67c1ddd3c1525aa4c2c4e162bd6435a485609f6bd76c8ff73a7b5d043e4724458594703245fabdb479ef2786c757b35932a645399f2703647785b59b971970e6bccef3e6cd6fae39f9f135203eb104f0db20cf48e461cb7d824889c0d5d6a47cd0bf213c2f7acb3ddbd3effefebb4f60458ffc8b6ff1e4cc447")
	dec, err := DecryptOAEP(sha256.New(), r, k, enc, []byte("label"))
	if err != nil {
		t.Fatal(err)
	}
	want := []byte("hello")
	if !bytes.Equal(dec, want) {
		t.Fatalf("DecryptOAEP: wrong dec\nhave %x\nwant %x", dec, want)
	}
	r.checkOffset(256)
}

func TestBoringFinalizers(t *testing.T) {
	if runtime.GOOS == "nacl" {
		// Times out on nacl (without BoringCrypto)
		// but not clear why - probably consuming rand.Reader too quickly
		// and being throttled. Also doesn't really matter.
		t.Skip("skipping on nacl")
	}

	k := testKey(t)

	// Run test with GOGC=10, to make bug more likely.
	// Without the KeepAlives, the loop usually dies after
	// about 30 iterations.
	defer debug.SetGCPercent(debug.SetGCPercent(10))
	for n := 0; n < 200; n++ {
		// Clear the underlying BoringCrypto object.
		atomic.StorePointer(&k.boring, nil)

		// Race to create the underlying BoringCrypto object.
		// The ones that lose the race are prime candidates for
		// being GC'ed too early if the finalizers are not being
		// used correctly.
		var wg sync.WaitGroup
		for i := 0; i < 10; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				sum := make([]byte, 32)
				_, err := SignPKCS1v15(rand.Reader, k, crypto.SHA256, sum)
				if err != nil {
					panic(err) // usually caused by memory corruption, so hard stop
				}
			}()
		}
		wg.Wait()
	}
}
