builder_test.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tka
  4. import (
  5. "crypto/ed25519"
  6. "strings"
  7. "testing"
  8. "github.com/google/go-cmp/cmp"
  9. "tailscale.com/types/tkatype"
  10. )
  11. type signer25519 ed25519.PrivateKey
  12. func (s signer25519) SignAUM(sigHash tkatype.AUMSigHash) ([]tkatype.Signature, error) {
  13. priv := ed25519.PrivateKey(s)
  14. key := Key{Kind: Key25519, Public: priv.Public().(ed25519.PublicKey)}
  15. return []tkatype.Signature{{
  16. KeyID: key.MustID(),
  17. Signature: ed25519.Sign(priv, sigHash[:]),
  18. }}, nil
  19. }
  20. func TestAuthorityBuilderAddKey(t *testing.T) {
  21. pub, priv := testingKey25519(t, 1)
  22. key := Key{Kind: Key25519, Public: pub, Votes: 2}
  23. storage := ChonkMem()
  24. a, _, err := Create(storage, State{
  25. Keys: []Key{key},
  26. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  27. }, signer25519(priv))
  28. if err != nil {
  29. t.Fatalf("Create() failed: %v", err)
  30. }
  31. pub2, _ := testingKey25519(t, 2)
  32. key2 := Key{Kind: Key25519, Public: pub2, Votes: 1}
  33. b := a.NewUpdater(signer25519(priv))
  34. if err := b.AddKey(key2); err != nil {
  35. t.Fatalf("AddKey(%v) failed: %v", key2, err)
  36. }
  37. updates, err := b.Finalize(storage)
  38. if err != nil {
  39. t.Fatalf("Finalize() failed: %v", err)
  40. }
  41. // See if the update is valid by applying it to the authority
  42. // + checking if the new key is there.
  43. if err := a.Inform(storage, updates); err != nil {
  44. t.Fatalf("could not apply generated updates: %v", err)
  45. }
  46. if _, err := a.state.GetKey(key2.MustID()); err != nil {
  47. t.Errorf("could not read new key: %v", err)
  48. }
  49. }
  50. func TestAuthorityBuilderMaxKey(t *testing.T) {
  51. pub, priv := testingKey25519(t, 1)
  52. key := Key{Kind: Key25519, Public: pub, Votes: 2}
  53. storage := ChonkMem()
  54. a, _, err := Create(storage, State{
  55. Keys: []Key{key},
  56. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  57. }, signer25519(priv))
  58. if err != nil {
  59. t.Fatalf("Create() failed: %v", err)
  60. }
  61. for i := 0; i <= maxKeys; i++ {
  62. pub2, _ := testingKey25519(t, int64(2+i))
  63. key2 := Key{Kind: Key25519, Public: pub2, Votes: 1}
  64. b := a.NewUpdater(signer25519(priv))
  65. err := b.AddKey(key2)
  66. if i < maxKeys-1 {
  67. if err != nil {
  68. t.Fatalf("AddKey(%v) failed: %v", key2, err)
  69. }
  70. } else {
  71. // Too many keys.
  72. if err == nil {
  73. t.Fatalf("AddKey(%v) succeeded unexpectedly", key2)
  74. }
  75. continue
  76. }
  77. updates, err := b.Finalize(storage)
  78. if err != nil {
  79. t.Fatalf("Finalize() failed: %v", err)
  80. }
  81. if err := a.Inform(storage, updates); err != nil {
  82. t.Fatalf("could not apply generated updates: %v", err)
  83. }
  84. if _, err := a.state.GetKey(key2.MustID()); err != nil {
  85. t.Errorf("could not read new key: %v", err)
  86. }
  87. }
  88. }
  89. func TestAuthorityBuilderRemoveKey(t *testing.T) {
  90. pub, priv := testingKey25519(t, 1)
  91. key := Key{Kind: Key25519, Public: pub, Votes: 2}
  92. pub2, _ := testingKey25519(t, 2)
  93. key2 := Key{Kind: Key25519, Public: pub2, Votes: 1}
  94. storage := ChonkMem()
  95. a, _, err := Create(storage, State{
  96. Keys: []Key{key, key2},
  97. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  98. }, signer25519(priv))
  99. if err != nil {
  100. t.Fatalf("Create() failed: %v", err)
  101. }
  102. b := a.NewUpdater(signer25519(priv))
  103. if err := b.RemoveKey(key2.MustID()); err != nil {
  104. t.Fatalf("RemoveKey(%v) failed: %v", key2, err)
  105. }
  106. updates, err := b.Finalize(storage)
  107. if err != nil {
  108. t.Fatalf("Finalize() failed: %v", err)
  109. }
  110. // See if the update is valid by applying it to the authority
  111. // + checking if the key has been removed.
  112. if err := a.Inform(storage, updates); err != nil {
  113. t.Fatalf("could not apply generated updates: %v", err)
  114. }
  115. if _, err := a.state.GetKey(key2.MustID()); err != ErrNoSuchKey {
  116. t.Errorf("GetKey(key2).err = %v, want %v", err, ErrNoSuchKey)
  117. }
  118. // Check that removing the remaining key errors out.
  119. b = a.NewUpdater(signer25519(priv))
  120. if err := b.RemoveKey(key.MustID()); err != nil {
  121. t.Fatalf("RemoveKey(%v) failed: %v", key, err)
  122. }
  123. updates, err = b.Finalize(storage)
  124. if err != nil {
  125. t.Fatalf("Finalize() failed: %v", err)
  126. }
  127. wantErr := "cannot remove the last key"
  128. if err := a.Inform(storage, updates); err == nil || !strings.Contains(err.Error(), wantErr) {
  129. t.Fatalf("expected Inform() to return error %q, got: %v", wantErr, err)
  130. }
  131. }
  132. func TestAuthorityBuilderSetKeyVote(t *testing.T) {
  133. pub, priv := testingKey25519(t, 1)
  134. key := Key{Kind: Key25519, Public: pub, Votes: 2}
  135. storage := ChonkMem()
  136. a, _, err := Create(storage, State{
  137. Keys: []Key{key},
  138. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  139. }, signer25519(priv))
  140. if err != nil {
  141. t.Fatalf("Create() failed: %v", err)
  142. }
  143. b := a.NewUpdater(signer25519(priv))
  144. if err := b.SetKeyVote(key.MustID(), 5); err != nil {
  145. t.Fatalf("SetKeyVote(%v) failed: %v", key.MustID(), err)
  146. }
  147. updates, err := b.Finalize(storage)
  148. if err != nil {
  149. t.Fatalf("Finalize() failed: %v", err)
  150. }
  151. // See if the update is valid by applying it to the authority
  152. // + checking if the update is there.
  153. if err := a.Inform(storage, updates); err != nil {
  154. t.Fatalf("could not apply generated updates: %v", err)
  155. }
  156. k, err := a.state.GetKey(key.MustID())
  157. if err != nil {
  158. t.Fatal(err)
  159. }
  160. if got, want := k.Votes, uint(5); got != want {
  161. t.Errorf("key.Votes = %d, want %d", got, want)
  162. }
  163. }
  164. func TestAuthorityBuilderSetKeyMeta(t *testing.T) {
  165. pub, priv := testingKey25519(t, 1)
  166. key := Key{Kind: Key25519, Public: pub, Votes: 2, Meta: map[string]string{"a": "b"}}
  167. storage := ChonkMem()
  168. a, _, err := Create(storage, State{
  169. Keys: []Key{key},
  170. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  171. }, signer25519(priv))
  172. if err != nil {
  173. t.Fatalf("Create() failed: %v", err)
  174. }
  175. b := a.NewUpdater(signer25519(priv))
  176. if err := b.SetKeyMeta(key.MustID(), map[string]string{"b": "c"}); err != nil {
  177. t.Fatalf("SetKeyMeta(%v) failed: %v", key, err)
  178. }
  179. updates, err := b.Finalize(storage)
  180. if err != nil {
  181. t.Fatalf("Finalize() failed: %v", err)
  182. }
  183. // See if the update is valid by applying it to the authority
  184. // + checking if the update is there.
  185. if err := a.Inform(storage, updates); err != nil {
  186. t.Fatalf("could not apply generated updates: %v", err)
  187. }
  188. k, err := a.state.GetKey(key.MustID())
  189. if err != nil {
  190. t.Fatal(err)
  191. }
  192. if diff := cmp.Diff(map[string]string{"b": "c"}, k.Meta); diff != "" {
  193. t.Errorf("updated meta differs (-want, +got):\n%s", diff)
  194. }
  195. }
  196. func TestAuthorityBuilderMultiple(t *testing.T) {
  197. pub, priv := testingKey25519(t, 1)
  198. key := Key{Kind: Key25519, Public: pub, Votes: 2}
  199. storage := ChonkMem()
  200. a, _, err := Create(storage, State{
  201. Keys: []Key{key},
  202. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  203. }, signer25519(priv))
  204. if err != nil {
  205. t.Fatalf("Create() failed: %v", err)
  206. }
  207. pub2, _ := testingKey25519(t, 2)
  208. key2 := Key{Kind: Key25519, Public: pub2, Votes: 1}
  209. b := a.NewUpdater(signer25519(priv))
  210. if err := b.AddKey(key2); err != nil {
  211. t.Fatalf("AddKey(%v) failed: %v", key2, err)
  212. }
  213. if err := b.SetKeyVote(key2.MustID(), 42); err != nil {
  214. t.Fatalf("SetKeyVote(%v) failed: %v", key2, err)
  215. }
  216. if err := b.RemoveKey(key.MustID()); err != nil {
  217. t.Fatalf("RemoveKey(%v) failed: %v", key, err)
  218. }
  219. updates, err := b.Finalize(storage)
  220. if err != nil {
  221. t.Fatalf("Finalize() failed: %v", err)
  222. }
  223. // See if the update is valid by applying it to the authority
  224. // + checking if the update is there.
  225. if err := a.Inform(storage, updates); err != nil {
  226. t.Fatalf("could not apply generated updates: %v", err)
  227. }
  228. k, err := a.state.GetKey(key2.MustID())
  229. if err != nil {
  230. t.Fatal(err)
  231. }
  232. if got, want := k.Votes, uint(42); got != want {
  233. t.Errorf("key.Votes = %d, want %d", got, want)
  234. }
  235. if _, err := a.state.GetKey(key.MustID()); err != ErrNoSuchKey {
  236. t.Errorf("GetKey(key).err = %v, want %v", err, ErrNoSuchKey)
  237. }
  238. }
  239. func TestAuthorityBuilderCheckpointsAfterXUpdates(t *testing.T) {
  240. pub, priv := testingKey25519(t, 1)
  241. key := Key{Kind: Key25519, Public: pub, Votes: 2}
  242. storage := ChonkMem()
  243. a, _, err := Create(storage, State{
  244. Keys: []Key{key},
  245. DisablementSecrets: [][]byte{DisablementKDF([]byte{1, 2, 3})},
  246. }, signer25519(priv))
  247. if err != nil {
  248. t.Fatalf("Create() failed: %v", err)
  249. }
  250. for i := 0; i <= checkpointEvery; i++ {
  251. pub2, _ := testingKey25519(t, int64(i+2))
  252. key2 := Key{Kind: Key25519, Public: pub2, Votes: 1}
  253. b := a.NewUpdater(signer25519(priv))
  254. if err := b.AddKey(key2); err != nil {
  255. t.Fatalf("AddKey(%v) failed: %v", key2, err)
  256. }
  257. updates, err := b.Finalize(storage)
  258. if err != nil {
  259. t.Fatalf("Finalize() failed: %v", err)
  260. }
  261. // See if the update is valid by applying it to the authority
  262. // + checking if the new key is there.
  263. if err := a.Inform(storage, updates); err != nil {
  264. t.Fatalf("could not apply generated updates: %v", err)
  265. }
  266. if _, err := a.state.GetKey(key2.MustID()); err != nil {
  267. t.Fatal(err)
  268. }
  269. wantKind := AUMAddKey
  270. if i == checkpointEvery-1 { // Genesis + 49 updates == 50 (the value of checkpointEvery)
  271. wantKind = AUMCheckpoint
  272. }
  273. lastAUM, err := storage.AUM(a.Head())
  274. if err != nil {
  275. t.Fatal(err)
  276. }
  277. if lastAUM.MessageKind != wantKind {
  278. t.Errorf("[%d] HeadAUM.MessageKind = %v, want %v", i, lastAUM.MessageKind, wantKind)
  279. }
  280. }
  281. // Try starting an authority just based on storage.
  282. a2, err := Open(storage)
  283. if err != nil {
  284. t.Fatalf("Failed to open from stored AUMs: %v", err)
  285. }
  286. if a.Head() != a2.Head() {
  287. t.Errorf("stored and computed HEAD differ: got %v, want %v", a2.Head(), a.Head())
  288. }
  289. }