key_test.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tka
  4. import (
  5. "bytes"
  6. "crypto/ed25519"
  7. "encoding/binary"
  8. "math/rand"
  9. "testing"
  10. "tailscale.com/types/key"
  11. "tailscale.com/types/tkatype"
  12. )
  13. // returns a random source based on the test name + extraSeed.
  14. func testingRand(t *testing.T, extraSeed int64) *rand.Rand {
  15. var seed int64
  16. if err := binary.Read(bytes.NewBuffer([]byte(t.Name())), binary.LittleEndian, &seed); err != nil {
  17. panic(err)
  18. }
  19. return rand.New(rand.NewSource(seed + extraSeed))
  20. }
  21. // generates a 25519 private key based on the seed + test name.
  22. func testingKey25519(t *testing.T, seed int64) (ed25519.PublicKey, ed25519.PrivateKey) {
  23. pub, priv, err := ed25519.GenerateKey(testingRand(t, seed))
  24. if err != nil {
  25. panic(err)
  26. }
  27. return pub, priv
  28. }
  29. func TestVerify25519(t *testing.T) {
  30. pub, priv := testingKey25519(t, 1)
  31. key := Key{
  32. Kind: Key25519,
  33. Public: pub,
  34. }
  35. aum := AUM{
  36. MessageKind: AUMRemoveKey,
  37. KeyID: []byte{1, 2, 3, 4},
  38. // Signatures is set to crap so we are sure it's ignored in the sigHash computation.
  39. Signatures: []tkatype.Signature{{KeyID: []byte{45, 42}}},
  40. }
  41. sigHash := aum.SigHash()
  42. aum.Signatures = []tkatype.Signature{
  43. {
  44. KeyID: key.MustID(),
  45. Signature: ed25519.Sign(priv, sigHash[:]),
  46. },
  47. }
  48. if err := signatureVerify(&aum.Signatures[0], aum.SigHash(), key); err != nil {
  49. t.Errorf("signature verification failed: %v", err)
  50. }
  51. // Make sure it fails with a different public key.
  52. pub2, _ := testingKey25519(t, 2)
  53. key2 := Key{Kind: Key25519, Public: pub2}
  54. if err := signatureVerify(&aum.Signatures[0], aum.SigHash(), key2); err == nil {
  55. t.Error("signature verification with different key did not fail")
  56. }
  57. }
  58. func TestNLPrivate(t *testing.T) {
  59. p := key.NewNLPrivate()
  60. pub := p.Public()
  61. // Test that key.NLPrivate implements Signer by making a new
  62. // authority.
  63. k := Key{Kind: Key25519, Public: pub.Verifier(), Votes: 1}
  64. _, aum, err := Create(ChonkMem(), State{
  65. Keys: []Key{k},
  66. DisablementSecrets: [][]byte{bytes.Repeat([]byte{1}, 32)},
  67. }, p)
  68. if err != nil {
  69. t.Fatalf("Create() failed: %v", err)
  70. }
  71. // Make sure the generated genesis AUM was signed.
  72. if got, want := len(aum.Signatures), 1; got != want {
  73. t.Fatalf("len(signatures) = %d, want %d", got, want)
  74. }
  75. sigHash := aum.SigHash()
  76. if ok := ed25519.Verify(pub.Verifier(), sigHash[:], aum.Signatures[0].Signature); !ok {
  77. t.Error("signature did not verify")
  78. }
  79. // We manually compute the keyID, so make sure it's consistent with
  80. // tka.Key.ID().
  81. if !bytes.Equal(k.MustID(), p.KeyID()) {
  82. t.Errorf("private.KeyID() & tka KeyID differ: %x != %x", k.MustID(), p.KeyID())
  83. }
  84. }