...

Source file src/golang.org/x/mod/sumdb/note/note_test.go

Documentation: golang.org/x/mod/sumdb/note

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package note
     6  
     7  import (
     8  	"crypto/ed25519"
     9  	"crypto/rand"
    10  	"errors"
    11  	"strings"
    12  	"testing"
    13  	"testing/iotest"
    14  )
    15  
    16  func TestNewVerifier(t *testing.T) {
    17  	vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
    18  	_, err := NewVerifier(vkey)
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  
    23  	// Check various manglings are not accepted.
    24  	badKey := func(k string) {
    25  		_, err := NewVerifier(k)
    26  		if err == nil {
    27  			t.Errorf("NewVerifier(%q) succeeded, should have failed", k)
    28  		}
    29  	}
    30  
    31  	b := []byte(vkey)
    32  	for i := 0; i <= len(b); i++ {
    33  		for j := i + 1; j <= len(b); j++ {
    34  			if i != 0 || j != len(b) {
    35  				badKey(string(b[i:j]))
    36  			}
    37  		}
    38  	}
    39  	for i := 0; i < len(b); i++ {
    40  		b[i]++
    41  		badKey(string(b))
    42  		b[i]--
    43  	}
    44  
    45  	badKey("PeterNeumann+cc469956+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TWBADKEY==") // wrong length key, with adjusted key hash
    46  	badKey("PeterNeumann+173116ae+ZRpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW")         // unknown algorithm, with adjusted key hash
    47  }
    48  
    49  func TestNewSigner(t *testing.T) {
    50  	skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
    51  	_, err := NewSigner(skey)
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	// Check various manglings are not accepted.
    57  	b := []byte(skey)
    58  	for i := 0; i <= len(b); i++ {
    59  		for j := i + 1; j <= len(b); j++ {
    60  			if i == 0 && j == len(b) {
    61  				continue
    62  			}
    63  			_, err := NewSigner(string(b[i:j]))
    64  			if err == nil {
    65  				t.Errorf("NewSigner(%q) succeeded, should have failed", b[i:j])
    66  			}
    67  		}
    68  	}
    69  	for i := 0; i < len(b); i++ {
    70  		b[i]++
    71  		_, err := NewSigner(string(b))
    72  		if err == nil {
    73  			t.Errorf("NewSigner(%q) succeeded, should have failed", b)
    74  		}
    75  		b[i]--
    76  	}
    77  }
    78  
    79  func testSignerAndVerifier(t *testing.T, Name string, signer Signer, verifier Verifier) {
    80  	if name := signer.Name(); name != Name {
    81  		t.Errorf("signer.Name() = %q, want %q", name, Name)
    82  	}
    83  	if name := verifier.Name(); name != Name {
    84  		t.Errorf("verifier.Name() = %q, want %q", name, Name)
    85  	}
    86  	shash := signer.KeyHash()
    87  	vhash := verifier.KeyHash()
    88  	if shash != vhash {
    89  		t.Errorf("signer.KeyHash() = %#08x != verifier.KeyHash() = %#08x", shash, vhash)
    90  	}
    91  
    92  	msg := []byte("hi")
    93  	sig, err := signer.Sign(msg)
    94  	if err != nil {
    95  		t.Fatalf("signer.Sign: %v", err)
    96  	}
    97  	if !verifier.Verify(msg, sig) {
    98  		t.Fatalf("verifier.Verify failed on signature returned by signer.Sign")
    99  	}
   100  	sig[0]++
   101  	if verifier.Verify(msg, sig) {
   102  		t.Fatalf("verifier.Verify succeeded on corrupt signature")
   103  	}
   104  	sig[0]--
   105  	msg[0]++
   106  	if verifier.Verify(msg, sig) {
   107  		t.Fatalf("verifier.Verify succeeded on corrupt message")
   108  	}
   109  }
   110  
   111  func TestGenerateKey(t *testing.T) {
   112  	// Generate key pair, make sure it is all self-consistent.
   113  	const Name = "EnochRoot"
   114  
   115  	skey, vkey, err := GenerateKey(rand.Reader, Name)
   116  	if err != nil {
   117  		t.Fatalf("GenerateKey: %v", err)
   118  	}
   119  	signer, err := NewSigner(skey)
   120  	if err != nil {
   121  		t.Fatalf("NewSigner: %v", err)
   122  	}
   123  	verifier, err := NewVerifier(vkey)
   124  	if err != nil {
   125  		t.Fatalf("NewVerifier: %v", err)
   126  	}
   127  
   128  	testSignerAndVerifier(t, Name, signer, verifier)
   129  
   130  	// Check that GenerateKey returns error from rand reader.
   131  	_, _, err = GenerateKey(iotest.TimeoutReader(iotest.OneByteReader(rand.Reader)), Name)
   132  	if err == nil {
   133  		t.Fatalf("GenerateKey succeeded with error-returning rand reader")
   134  	}
   135  }
   136  
   137  func TestFromEd25519(t *testing.T) {
   138  	const Name = "EnochRoot"
   139  
   140  	pub, priv, err := ed25519.GenerateKey(rand.Reader)
   141  	if err != nil {
   142  		t.Fatalf("GenerateKey: %v", err)
   143  	}
   144  	signer, err := newSignerFromEd25519Seed(Name, priv.Seed())
   145  	if err != nil {
   146  		t.Fatalf("newSignerFromEd25519Seed: %v", err)
   147  	}
   148  	vkey, err := NewEd25519VerifierKey(Name, pub)
   149  	if err != nil {
   150  		t.Fatalf("NewEd25519VerifierKey: %v", err)
   151  	}
   152  	verifier, err := NewVerifier(vkey)
   153  	if err != nil {
   154  		t.Fatalf("NewVerifier: %v", err)
   155  	}
   156  
   157  	testSignerAndVerifier(t, Name, signer, verifier)
   158  
   159  	// Check that wrong key sizes return errors.
   160  	_, err = NewEd25519VerifierKey(Name, pub[:len(pub)-1])
   161  	if err == nil {
   162  		t.Errorf("NewEd25519VerifierKey succeeded with a seed of the wrong size")
   163  	}
   164  }
   165  
   166  // newSignerFromEd25519Seed constructs a new signer from a verifier name and a
   167  // crypto/ed25519 private key seed.
   168  func newSignerFromEd25519Seed(name string, seed []byte) (Signer, error) {
   169  	if len(seed) != ed25519.SeedSize {
   170  		return nil, errors.New("invalid seed size")
   171  	}
   172  	priv := ed25519.NewKeyFromSeed(seed)
   173  	pub := priv[32:]
   174  
   175  	pubkey := append([]byte{algEd25519}, pub...)
   176  	hash := keyHash(name, pubkey)
   177  
   178  	s := &signer{
   179  		name: name,
   180  		hash: hash,
   181  		sign: func(msg []byte) ([]byte, error) {
   182  			return ed25519.Sign(priv, msg), nil
   183  		},
   184  	}
   185  	return s, nil
   186  }
   187  
   188  func TestSign(t *testing.T) {
   189  	skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
   190  	text := "If you think cryptography is the answer to your problem,\n" +
   191  		"then you don't know what your problem is.\n"
   192  
   193  	signer, err := NewSigner(skey)
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  
   198  	msg, err := Sign(&Note{Text: text}, signer)
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  
   203  	want := `If you think cryptography is the answer to your problem,
   204  then you don't know what your problem is.
   205  
   206  — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
   207  `
   208  	if string(msg) != want {
   209  		t.Errorf("Sign: wrong output\nhave:\n%s\nwant:\n%s", msg, want)
   210  	}
   211  
   212  	// Check that existing signature is replaced by new one.
   213  	msg, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "PeterNeumann", Hash: 0xc74f20a3, Base64: "BADSIGN="}}}, signer)
   214  	if err != nil {
   215  		t.Fatal(err)
   216  	}
   217  	if string(msg) != want {
   218  		t.Errorf("Sign replacing signature: wrong output\nhave:\n%s\nwant:\n%s", msg, want)
   219  	}
   220  
   221  	// Check various bad inputs.
   222  	_, err = Sign(&Note{Text: "abc"}, signer)
   223  	if err == nil || err.Error() != "malformed note" {
   224  		t.Fatalf("Sign with short text: %v, want malformed note error", err)
   225  	}
   226  
   227  	_, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "a+b", Base64: "ABCD"}}})
   228  	if err == nil || err.Error() != "malformed note" {
   229  		t.Fatalf("Sign with bad name: %v, want malformed note error", err)
   230  	}
   231  
   232  	_, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "PeterNeumann", Hash: 0xc74f20a3, Base64: "BADHASH="}}})
   233  	if err == nil || err.Error() != "malformed note" {
   234  		t.Fatalf("Sign with bad pre-filled signature: %v, want malformed note error", err)
   235  	}
   236  
   237  	_, err = Sign(&Note{Text: text}, &badSigner{signer})
   238  	if err == nil || err.Error() != "invalid signer" {
   239  		t.Fatalf("Sign with bad signer: %v, want invalid signer error", err)
   240  	}
   241  
   242  	_, err = Sign(&Note{Text: text}, &errSigner{signer})
   243  	if err != errSurprise {
   244  		t.Fatalf("Sign with failing signer: %v, want errSurprise", err)
   245  	}
   246  }
   247  
   248  func TestVerifierList(t *testing.T) {
   249  	peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
   250  	peterVerifier, err := NewVerifier(peterKey)
   251  	if err != nil {
   252  		t.Fatal(err)
   253  	}
   254  
   255  	enochKey := "EnochRoot+af0cfe78+ATtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop"
   256  	enochVerifier, err := NewVerifier(enochKey)
   257  	if err != nil {
   258  		t.Fatal(err)
   259  	}
   260  
   261  	list := VerifierList(peterVerifier, enochVerifier, enochVerifier)
   262  	v, err := list.Verifier("PeterNeumann", 0xc74f20a3)
   263  	if v != peterVerifier || err != nil {
   264  		t.Fatalf("list.Verifier(peter) = %v, %v, want %v, nil", v, err, peterVerifier)
   265  	}
   266  	v, err = list.Verifier("PeterNeumann", 0xc74f20a4)
   267  	if v != nil || err == nil || err.Error() != "unknown key PeterNeumann+c74f20a4" {
   268  		t.Fatalf("list.Verifier(peter bad hash) = %v, %v, want nil, unknown key error", v, err)
   269  	}
   270  
   271  	v, err = list.Verifier("PeterNeuman", 0xc74f20a3)
   272  	if v != nil || err == nil || err.Error() != "unknown key PeterNeuman+c74f20a3" {
   273  		t.Fatalf("list.Verifier(peter bad name) = %v, %v, want nil, unknown key error", v, err)
   274  	}
   275  	v, err = list.Verifier("EnochRoot", 0xaf0cfe78)
   276  	if v != nil || err == nil || err.Error() != "ambiguous key EnochRoot+af0cfe78" {
   277  		t.Fatalf("list.Verifier(enoch) = %v, %v, want nil, ambiguous key error", v, err)
   278  	}
   279  }
   280  
   281  type badSigner struct {
   282  	Signer
   283  }
   284  
   285  func (b *badSigner) Name() string {
   286  	return "bad name"
   287  }
   288  
   289  var errSurprise = errors.New("surprise!")
   290  
   291  type errSigner struct {
   292  	Signer
   293  }
   294  
   295  func (e *errSigner) Sign([]byte) ([]byte, error) {
   296  	return nil, errSurprise
   297  }
   298  
   299  type fixedVerifier struct{ v Verifier }
   300  
   301  func (v fixedVerifier) Verifier(name string, hash uint32) (Verifier, error) {
   302  	return v.v, nil
   303  }
   304  
   305  func TestOpen(t *testing.T) {
   306  	peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
   307  	peterVerifier, err := NewVerifier(peterKey)
   308  	if err != nil {
   309  		t.Fatal(err)
   310  	}
   311  
   312  	enochKey := "EnochRoot+af0cfe78+ATtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop"
   313  	enochVerifier, err := NewVerifier(enochKey)
   314  	if err != nil {
   315  		t.Fatal(err)
   316  	}
   317  
   318  	text := `If you think cryptography is the answer to your problem,
   319  then you don't know what your problem is.
   320  `
   321  	peterSig := "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n"
   322  	enochSig := "— EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=\n"
   323  
   324  	peter := Signature{"PeterNeumann", 0xc74f20a3, "x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM="}
   325  	enoch := Signature{"EnochRoot", 0xaf0cfe78, "rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ="}
   326  
   327  	// Check one signature verified, one not.
   328  	n, err := Open([]byte(text+"\n"+peterSig+enochSig), VerifierList(peterVerifier))
   329  	if err != nil {
   330  		t.Fatal(err)
   331  	}
   332  	if n.Text != text {
   333  		t.Errorf("n.Text = %q, want %q", n.Text, text)
   334  	}
   335  	if len(n.Sigs) != 1 || n.Sigs[0] != peter {
   336  		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter})
   337  	}
   338  	if len(n.UnverifiedSigs) != 1 || n.UnverifiedSigs[0] != enoch {
   339  		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter})
   340  	}
   341  
   342  	// Check both verified.
   343  	n, err = Open([]byte(text+"\n"+peterSig+enochSig), VerifierList(peterVerifier, enochVerifier))
   344  	if err != nil {
   345  		t.Fatal(err)
   346  	}
   347  	if len(n.Sigs) != 2 || n.Sigs[0] != peter || n.Sigs[1] != enoch {
   348  		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter, enoch})
   349  	}
   350  	if len(n.UnverifiedSigs) != 0 {
   351  		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{})
   352  	}
   353  
   354  	// Check both unverified.
   355  	n, err = Open([]byte(text+"\n"+peterSig+enochSig), VerifierList())
   356  	if n != nil || err == nil {
   357  		t.Fatalf("Open unverified = %v, %v, want nil, error", n, err)
   358  	}
   359  	e, ok := err.(*UnverifiedNoteError)
   360  	if !ok {
   361  		t.Fatalf("Open unverified: err is %T, want *UnverifiedNoteError", err)
   362  	}
   363  	if err.Error() != "note has no verifiable signatures" {
   364  		t.Fatalf("Open unverified: err.Error() = %q, want %q", err.Error(), "note has no verifiable signatures")
   365  	}
   366  
   367  	n = e.Note
   368  	if n == nil {
   369  		t.Fatalf("Open unverified: missing note in UnverifiedNoteError")
   370  	}
   371  	if len(n.Sigs) != 0 {
   372  		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{})
   373  	}
   374  	if len(n.UnverifiedSigs) != 2 || n.UnverifiedSigs[0] != peter || n.UnverifiedSigs[1] != enoch {
   375  		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter, enoch})
   376  	}
   377  
   378  	// Check duplicated verifier.
   379  	_, err = Open([]byte(text+"\n"+enochSig), VerifierList(enochVerifier, peterVerifier, enochVerifier))
   380  	if err == nil || err.Error() != "ambiguous key EnochRoot+af0cfe78" {
   381  		t.Fatalf("Open with duplicated verifier: err=%v, want ambiguous key", err)
   382  	}
   383  
   384  	// Check unused duplicated verifier.
   385  	_, err = Open([]byte(text+"\n"+peterSig), VerifierList(enochVerifier, peterVerifier, enochVerifier))
   386  	if err != nil {
   387  		t.Fatal(err)
   388  	}
   389  
   390  	// Check too many signatures.
   391  	n, err = Open([]byte(text+"\n"+strings.Repeat(peterSig, 101)), VerifierList(peterVerifier))
   392  	if n != nil || err == nil || err.Error() != "malformed note" {
   393  		t.Fatalf("Open too many verified signatures = %v, %v, want nil, malformed note error", n, err)
   394  	}
   395  	n, err = Open([]byte(text+"\n"+strings.Repeat(peterSig, 101)), VerifierList())
   396  	if n != nil || err == nil || err.Error() != "malformed note" {
   397  		t.Fatalf("Open too many verified signatures = %v, %v, want nil, malformed note error", n, err)
   398  	}
   399  
   400  	// Invalid signature.
   401  	n, err = Open([]byte(text+"\n"+peterSig[:60]+"ABCD"+peterSig[60:]), VerifierList(peterVerifier))
   402  	if n != nil || err == nil || err.Error() != "invalid signature for key PeterNeumann+c74f20a3" {
   403  		t.Fatalf("Open too many verified signatures = %v, %v, want nil, invalid signature error", n, err)
   404  	}
   405  
   406  	// Duplicated verified and unverified signatures.
   407  	enochABCD := Signature{"EnochRoot", 0xaf0cfe78, "rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n" + "ABCD" + "2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ="}
   408  	n, err = Open([]byte(text+"\n"+peterSig+peterSig+enochSig+enochSig+enochSig[:60]+"ABCD"+enochSig[60:]), VerifierList(peterVerifier))
   409  	if err != nil {
   410  		t.Fatal(err)
   411  	}
   412  	if len(n.Sigs) != 1 || n.Sigs[0] != peter {
   413  		t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter})
   414  	}
   415  	if len(n.UnverifiedSigs) != 2 || n.UnverifiedSigs[0] != enoch || n.UnverifiedSigs[1] != enochABCD {
   416  		t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.UnverifiedSigs, []Signature{enoch, enochABCD})
   417  	}
   418  
   419  	// Invalid encoded message syntax.
   420  	badMsgs := []string{
   421  		text,
   422  		text + "\n",
   423  		text + "\n" + peterSig[:len(peterSig)-1],
   424  		"\x01" + text + "\n" + peterSig,
   425  		"\xff" + text + "\n" + peterSig,
   426  		text + "\n" + "— Bad Name x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=",
   427  		text + "\n" + peterSig + "Unexpected line.\n",
   428  	}
   429  	for _, msg := range badMsgs {
   430  		n, err := Open([]byte(msg), VerifierList(peterVerifier))
   431  		if n != nil || err == nil || err.Error() != "malformed note" {
   432  			t.Fatalf("Open bad msg = %v, %v, want nil, malformed note error\nmsg:\n%s", n, err, msg)
   433  		}
   434  	}
   435  
   436  	// Verifiers returns a Verifier for the wrong name or hash.
   437  	misnamedSig := strings.Replace(peterSig, "PeterNeumann", "CarmenSandiego", -1)
   438  	_, err = Open([]byte(text+"\n"+misnamedSig), fixedVerifier{peterVerifier})
   439  	if err != errMismatchedVerifier {
   440  		t.Fatalf("Open with wrong Verifier, err=%v, want errMismatchedVerifier", err)
   441  	}
   442  	wrongHash := strings.Replace(peterSig, "x08g", "xxxx", -1)
   443  	_, err = Open([]byte(text+"\n"+wrongHash), fixedVerifier{peterVerifier})
   444  	if err != errMismatchedVerifier {
   445  		t.Fatalf("Open with wrong Verifier, err=%v, want errMismatchedVerifier", err)
   446  	}
   447  }
   448  
   449  func BenchmarkOpen(b *testing.B) {
   450  	vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
   451  	msg := []byte("If you think cryptography is the answer to your problem,\n" +
   452  		"then you don't know what your problem is.\n" +
   453  		"\n" +
   454  		"— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n")
   455  
   456  	verifier, err := NewVerifier(vkey)
   457  	if err != nil {
   458  		b.Fatal(err)
   459  	}
   460  	verifiers := VerifierList(verifier)
   461  	verifiers0 := VerifierList()
   462  
   463  	// Try with 0 signatures and 1 signature so we can tell how much each signature adds.
   464  
   465  	b.Run("Sig0", func(b *testing.B) {
   466  		for i := 0; i < b.N; i++ {
   467  			_, err := Open(msg, verifiers0)
   468  			e, ok := err.(*UnverifiedNoteError)
   469  			if !ok {
   470  				b.Fatal("expected UnverifiedNoteError")
   471  			}
   472  			n := e.Note
   473  			if len(n.Sigs) != 0 || len(n.UnverifiedSigs) != 1 {
   474  				b.Fatal("wrong signature count")
   475  			}
   476  		}
   477  	})
   478  
   479  	b.Run("Sig1", func(b *testing.B) {
   480  		for i := 0; i < b.N; i++ {
   481  			n, err := Open(msg, verifiers)
   482  			if err != nil {
   483  				b.Fatal(err)
   484  			}
   485  			if len(n.Sigs) != 1 || len(n.UnverifiedSigs) != 0 {
   486  				b.Fatal("wrong signature count")
   487  			}
   488  		}
   489  	})
   490  }
   491  

View as plain text