machine_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package key
  4. import (
  5. "bytes"
  6. "encoding/json"
  7. "strings"
  8. "testing"
  9. )
  10. func TestMachineKey(t *testing.T) {
  11. k := NewMachine()
  12. if k.IsZero() {
  13. t.Fatal("MachinePrivate should not be zero")
  14. }
  15. p := k.Public()
  16. if p.IsZero() {
  17. t.Fatal("MachinePublic should not be zero")
  18. }
  19. bs, err := p.MarshalText()
  20. if err != nil {
  21. t.Fatal(err)
  22. }
  23. if full, got := string(bs), ":"+p.UntypedHexString(); !strings.HasSuffix(full, got) {
  24. t.Fatalf("MachinePublic.UntypedHexString is not a suffix of the typed serialization, got %q want suffix of %q", got, full)
  25. }
  26. z := MachinePublic{}
  27. if !z.IsZero() {
  28. t.Fatal("IsZero(MachinePublic{}) is false")
  29. }
  30. if s := z.ShortString(); s != "" {
  31. t.Fatalf("MachinePublic{}.ShortString() is %q, want \"\"", s)
  32. }
  33. }
  34. func TestMachineSerialization(t *testing.T) {
  35. serialized := `{
  36. "Priv": "privkey:40ab1b58e9076c7a4d9d07291f5edf9d1aa017eb949624ba683317f48a640369",
  37. "Pub":"mkey:50d20b455ecf12bc453f83c2cfdb2a24925d06cf2598dcaa54e91af82ce9f765"
  38. }`
  39. // Carefully check that the expected serialized data decodes and
  40. // reencodes to the expected keys. These types are serialized to
  41. // disk all over the place and need to be stable.
  42. priv := MachinePrivate{
  43. k: [32]uint8{
  44. 0x40, 0xab, 0x1b, 0x58, 0xe9, 0x7, 0x6c, 0x7a, 0x4d, 0x9d, 0x7,
  45. 0x29, 0x1f, 0x5e, 0xdf, 0x9d, 0x1a, 0xa0, 0x17, 0xeb, 0x94,
  46. 0x96, 0x24, 0xba, 0x68, 0x33, 0x17, 0xf4, 0x8a, 0x64, 0x3, 0x69,
  47. },
  48. }
  49. pub := MachinePublic{
  50. k: [32]uint8{
  51. 0x50, 0xd2, 0xb, 0x45, 0x5e, 0xcf, 0x12, 0xbc, 0x45, 0x3f, 0x83,
  52. 0xc2, 0xcf, 0xdb, 0x2a, 0x24, 0x92, 0x5d, 0x6, 0xcf, 0x25, 0x98,
  53. 0xdc, 0xaa, 0x54, 0xe9, 0x1a, 0xf8, 0x2c, 0xe9, 0xf7, 0x65,
  54. },
  55. }
  56. type keypair struct {
  57. Priv MachinePrivate
  58. Pub MachinePublic
  59. }
  60. var a keypair
  61. if err := json.Unmarshal([]byte(serialized), &a); err != nil {
  62. t.Fatal(err)
  63. }
  64. if !a.Priv.Equal(priv) {
  65. t.Errorf("wrong deserialization of private key, got %#v want %#v", a.Priv, priv)
  66. }
  67. if a.Pub != pub {
  68. t.Errorf("wrong deserialization of public key, got %#v want %#v", a.Pub, pub)
  69. }
  70. bs, err := json.MarshalIndent(a, "", " ")
  71. if err != nil {
  72. t.Fatal(err)
  73. }
  74. var b bytes.Buffer
  75. json.Indent(&b, []byte(serialized), "", " ")
  76. if got, want := string(bs), b.String(); got != want {
  77. t.Error("json serialization doesn't roundtrip")
  78. }
  79. }
  80. func TestSealViaSharedKey(t *testing.T) {
  81. // encrypt a message from a to b
  82. a := NewMachine()
  83. b := NewMachine()
  84. apub, bpub := a.Public(), b.Public()
  85. shared := a.SharedKey(bpub)
  86. const clear = "the eagle flies at midnight"
  87. enc := shared.Seal([]byte(clear))
  88. back, ok := b.OpenFrom(apub, enc)
  89. if !ok {
  90. t.Fatal("failed to decrypt")
  91. }
  92. if string(back) != clear {
  93. t.Errorf("OpenFrom got %q; want cleartext %q", back, clear)
  94. }
  95. backShared, ok := shared.Open(enc)
  96. if !ok {
  97. t.Fatal("failed to decrypt from shared key")
  98. }
  99. if string(backShared) != clear {
  100. t.Errorf("Open got %q; want cleartext %q", back, clear)
  101. }
  102. }