<commit_before>package pgp

import (
	"bytes"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"

	"go.mozilla.org/autograph/signer"
)

func TestSignData(t *testing.T) {
	input := []byte("foobarbaz1234abcd")
	// initialize a signer
	s, err := New(pgpsignerconf)
	if err != nil {
		t.Fatalf("signer initialization failed with: %v", err)
	}
	if s.Config().Type != pgpsignerconf.Type {
		t.Fatalf("signer type %q does not match configuration %q", s.Config().Type, pgpsignerconf.Type)
	}
	if s.Config().ID != pgpsignerconf.ID {
		t.Fatalf("signer id %q does not match configuration %q", s.Config().ID, pgpsignerconf.ID)
	}
	if s.Config().PrivateKey != pgpsignerconf.PrivateKey {
		t.Fatalf("signer private key %q does not match configuration %q", s.Config().PrivateKey, pgpsignerconf.PrivateKey)
	}

	// sign input data
	sig, err := s.SignData(input, s.GetDefaultOptions())
	if err != nil {
		t.Fatalf("failed to sign data: %v", err)
	}
	// convert signature to string format
	sigstr, err := sig.Marshal()
	if err != nil {
		t.Fatalf("failed to marshal signature: %v", err)
	}

	// convert string format back to signature
	sig2, err := Unmarshal(sigstr)
	if err != nil {
		t.Fatalf("failed to unmarshal signature: %v", err)
	}

	if !bytes.Equal(sig.(*Signature).Data, sig2.(*Signature).Data) {
		t.Fatalf("marshalling signature changed its format.\nexpected\t%q\nreceived\t%q",
			sig.(*Signature).Data, sig2.(*Signature).Data)
	}
}

func TestSignAndVerifyWithGnuPG(t *testing.T) {
	input := []byte("foobarbaz1234abcd")

	// init a signer
	s, err := New(pgpsignerconf)
	if err != nil {
		t.Fatalf("failed to initialize signer: %v", err)
	}

	// sign input data
	sig, err := s.SignData(input, s.GetDefaultOptions())
	pgpSig, err := sig.Marshal()
	if err != nil {
		t.Fatal(err)
	}

	// write the signature to a temp file
	tmpSignatureFile, err := ioutil.TempFile("", "TestSignPGPAndVerifyWithGnuPG_signature")
	if err != nil {
		t.Fatal(err)
	}
	//defer os.Remove(tmpSignatureFile.Name())
	ioutil.WriteFile(tmpSignatureFile.Name(), []byte(pgpSig), 0755)

	// write the input to a temp file
	tmpContentFile, err := ioutil.TempFile("", "TestSignPGPAndVerifyWithGnuPG_input")
	if err != nil {
		t.Fatal(err)
	}
	//defer os.Remove(tmpContentFile.Name())
	ioutil.WriteFile(tmpContentFile.Name(), input, 0755)

	// write the public key to a temp file
	tmpPubKeyFile, err := ioutil.TempFile("", "TestSignPGPAndVerifyWithGnuPG_pubkey")
	if err != nil {
		t.Fatal(err)
	}
	//defer os.Remove(tmpIssuerCertFile.Name())
	fd, err := os.OpenFile(tmpPubKeyFile.Name(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		t.Fatal(err)
	}
	err = s.entity.Serialize(fd)
	if err != nil {
		t.Fatal(err)
	}
	fd.Close()

	// call gnupg to create a new keyring, load the key in it, then verify the signature
	gnupgCreateKeyring := exec.Command("gpg", "--no-default-keyring",
		"--keyring", "/tmp/autograph_pgp_keyring.gpg",
		"--secret-keyring", "/tmp/autograph_pgp_secring.gpg",
		"--import", tmpPubKeyFile.Name())
	out, err := gnupgCreateKeyring.CombinedOutput()
	if err != nil {
		t.Fatalf("failed to load public key into keyring: %s\n%s", err, out)
	}
	gnupgVerifySig := exec.Command("gpg", "--no-default-keyring",
		"--keyring", "/tmp/autograph_pgp_keyring.gpg",
		"--secret-keyring", "/tmp/autograph_pgp_secring.gpg",
		"--verify", tmpSignatureFile.Name(), tmpContentFile.Name())
	out, err = gnupgVerifySig.CombinedOutput()
	if err != nil {
		t.Fatalf("failed to load public key into keyring: %s\n%s", err, out)
	}
	//t.Logf("GnuPG PGP signature verification output:\n%s\n", out)
}

var pgpsignerconf = signer.Configuration{
	ID:   "pgptest",
	Type: Type,
	PrivateKey: `-----BEGIN PGP PRIVATE KEY BLOCK-----

lQOYBFuW9xABCACzCLYHwgGba7hi+lwhD/Hr5qqpg+UuN+88NclYgLWyl1nPpx2D
JvH6p7ASj2P9BzEp0XatXLO4/uPQY2UX9UpWLT5wDGOdX4QCvZvFk4whcXHtcamr
IQFTUjxRSIqvrq4t1h/4z635ztN0C6h5fWCxrCsoPJNQwEG/ZSDNXfwrJbsTIgus
X037WXAzCYKzDZg9dGcUon4F2DHGGGqjOqLsyaGvOvOPddhorESuAJRe6Tl9ijzT
NGc1uXIVEjEa5v9L4DJDqXYJqG35e0UuLkg0Wz4V9RVW/QP5DgnJAMQ8DUkXNHpa
eD1H9Zg/EBt3/85BGCR7u7J6MYvhuVnLIXQ1ABEBAAEAB/oCGkWPwOvAiuax/4V3
KAtPT9cMN3SMHtVQcj0OfeBGGKy9xUR21QNP/XWmcU9oyVbxNfIIIUzm1uGcy97i
ZBhbZ18m4ONsS6BaiZIP0n5RIt01WijOEUlgLBVkNpKFWKEbeYutUTxZ1hWvxYd9
bIP0hMH2Qs1Wbd4h6bucQg15KiCyL/6IeKJNnxR1MOKbBhoK46QbQKYeIIu0DT3D
8GJafr1xODNU9gCtEH55drmX9C7KEPhrOH8Sz9E99C8CpDV4QRfQfrd//ITxQ4pC
WrAJefQDv1T1Np9zapzs5EFXyO8tRBMw2IDRUvpE1a4ER9n7mCM9nu5Bbfq9DAFp
3cyBBADBy5X+9hwktP0kD1+l+ppbfpEvtnQXdyF+J9tt95yQEpPtMk3SUEVZ8cu2<commit_msg>fix pgp signer nits<commit_after>package pgp

import (
	"bytes"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"

	"go.mozilla.org/autograph/signer"
)

func TestSignData(t *testing.T) {
	input := []byte("foobarbaz1234abcd")
	// initialize a signer
	s, err := New(pgpsignerconf)
	if err != nil {
		t.Fatalf("signer initialization failed with: %v", err)
	}
	if s.Config().Type != pgpsignerconf.Type {
		t.Fatalf("signer type %q does not match configuration %q", s.Config().Type, pgpsignerconf.Type)
	}
	if s.Config().ID != pgpsignerconf.ID {
		t.Fatalf("signer id %q does not match configuration %q", s.Config().ID, pgpsignerconf.ID)
	}
	if s.Config().PrivateKey != pgpsignerconf.PrivateKey {
		t.Fatalf("signer private key %q does not match configuration %q", s.Config().PrivateKey, pgpsignerconf.PrivateKey)
	}

	// sign input data
	sig, err := s.SignData(input, s.GetDefaultOptions())
	if err != nil {
		t.Fatalf("failed to sign data: %v", err)
	}
	// convert signature to string format
	sigstr, err := sig.Marshal()
	if err != nil {
		t.Fatalf("failed to marshal signature: %v", err)
	}

	// convert string format back to signature
	sig2, err := Unmarshal(sigstr)
	if err != nil {
		t.Fatalf("failed to unmarshal signature: %v", err)
	}

	if !bytes.Equal(sig.(*Signature).Data, sig2.(*Signature).Data) {
		t.Fatalf("marshalling signature changed its format.\nexpected\t%q\nreceived\t%q",
			sig.(*Signature).Data, sig2.(*Signature).Data)
	}
}

func TestSignAndVerifyWithGnuPG(t *testing.T) {
	input := []byte("foobarbaz1234abcd")

	// init a signer
	s, err := New(pgpsignerconf)
	if err != nil {
		t.Fatalf("failed to initialize signer: %v", err)
	}

	// sign input data
	sig, err := s.SignData(input, s.GetDefaultOptions())
	pgpSig, err := sig.Marshal()
	if err != nil {
		t.Fatal(err)
	}

	// write the signature to a temp file
	tmpSignatureFile, err := ioutil.TempFile("", "TestSignPGPAndVerifyWithGnuPG_signature")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpSignatureFile.Name())
	ioutil.WriteFile(tmpSignatureFile.Name(), []byte(pgpSig), 0755)

	// write the input to a temp file
	tmpContentFile, err := ioutil.TempFile("", "TestSignPGPAndVerifyWithGnuPG_input")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpContentFile.Name())
	ioutil.WriteFile(tmpContentFile.Name(), input, 0755)

	// write the public key to a temp file
	tmpPubKeyFile, err := ioutil.TempFile("", "TestSignPGPAndVerifyWithGnuPG_pubkey")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(tmpPubKeyFile.Name())
	fd, err := os.OpenFile(tmpPubKeyFile.Name(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		t.Fatal(err)
	}
	err = s.entity.Serialize(fd)
	if err != nil {
		t.Fatal(err)
	}
	fd.Close()

	// call gnupg to create a new keyring, load the key in it, then verify the signature
	gnupgCreateKeyring := exec.Command("gpg", "--no-default-keyring",
		"--keyring", "/tmp/autograph_pgp_keyring.gpg",
		"--secret-keyring", "/tmp/autograph_pgp_secring.gpg",
		"--import", tmpPubKeyFile.Name())
	out, err := gnupgCreateKeyring.CombinedOutput()
	if err != nil {
		t.Fatalf("failed to load public key into keyring: %s\n%s", err, out)
	}
	gnupgVerifySig := exec.Command("gpg", "--no-default-keyring",
		"--keyring", "/tmp/autograph_pgp_keyring.gpg",
		"--secret-keyring", "/tmp/autograph_pgp_secring.gpg",
		"--verify", tmpSignatureFile.Name(), tmpContentFile.Name())
	out, err = gnupgVerifySig.CombinedOutput()
	if err != nil {
		t.Fatalf("failed to load public key into keyring: %s\n%s", err, out)
	}
	t.Logf("GnuPG PGP signature verification output:\n%s\n", out)
}

var pgpsignerconf = signer.Configuration{
	ID:   "pgptest",
	Type: Type,
	PrivateKey: `-----BEGIN PGP PRIVATE KEY BLOCK-----

<KEY>
{'fraction_non_alphanumeric': 0.14921722113502936, 'fraction_numerical': 0.021404109589041095, 'mean_word_length': 4.5853825136612025, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4083458', 'n_tokens_mistral': 3564, 'n_tokens_neox': 3377, 'n_words': 663}