1package vault
2
3import (
4	"bytes"
5	"reflect"
6	"testing"
7	"time"
8)
9
10func TestKeyring(t *testing.T) {
11	k := NewKeyring()
12
13	// Term should be 0
14	if term := k.ActiveTerm(); term != 0 {
15		t.Fatalf("bad: %d", term)
16	}
17
18	// Should have no key
19	if key := k.ActiveKey(); key != nil {
20		t.Fatalf("bad: %v", key)
21	}
22
23	// Add a key
24	testKey := []byte("testing")
25	key1 := &Key{Term: 1, Version: 1, Value: testKey, InstallTime: time.Now()}
26	k, err := k.AddKey(key1)
27	if err != nil {
28		t.Fatalf("err: %v", err)
29	}
30
31	// Term should be 1
32	if term := k.ActiveTerm(); term != 1 {
33		t.Fatalf("bad: %d", term)
34	}
35
36	// Should have key
37	key := k.ActiveKey()
38	if key == nil {
39		t.Fatalf("bad: %v", key)
40	}
41	if !bytes.Equal(key.Value, testKey) {
42		t.Fatalf("bad: %v", key)
43	}
44	if tKey := k.TermKey(1); tKey != key {
45		t.Fatalf("bad: %v", tKey)
46	}
47
48	// Should handle idempotent set
49	k, err = k.AddKey(key1)
50	if err != nil {
51		t.Fatalf("err: %v", err)
52	}
53
54	// Should not allow conflicting set
55	testConflict := []byte("nope")
56	key1Conf := &Key{Term: 1, Version: 1, Value: testConflict, InstallTime: time.Now()}
57	_, err = k.AddKey(key1Conf)
58	if err == nil {
59		t.Fatalf("err: %v", err)
60	}
61
62	// Add a new key
63	testSecond := []byte("second")
64	key2 := &Key{Term: 2, Version: 1, Value: testSecond, InstallTime: time.Now()}
65	k, err = k.AddKey(key2)
66	if err != nil {
67		t.Fatalf("err: %v", err)
68	}
69
70	// Term should be 2
71	if term := k.ActiveTerm(); term != 2 {
72		t.Fatalf("bad: %d", term)
73	}
74
75	// Should have key
76	newKey := k.ActiveKey()
77	if newKey == nil {
78		t.Fatalf("bad: %v", key)
79	}
80	if !bytes.Equal(newKey.Value, testSecond) {
81		t.Fatalf("bad: %v", key)
82	}
83	if tKey := k.TermKey(2); tKey != newKey {
84		t.Fatalf("bad: %v", tKey)
85	}
86
87	// Read of old key should work
88	if tKey := k.TermKey(1); tKey != key {
89		t.Fatalf("bad: %v", tKey)
90	}
91
92	// Remove the old key
93	k, err = k.RemoveKey(1)
94	if err != nil {
95		t.Fatalf("err: %v", err)
96	}
97
98	// Read of old key should not work
99	if tKey := k.TermKey(1); tKey != nil {
100		t.Fatalf("bad: %v", tKey)
101	}
102
103	// Remove the active key should fail
104	k, err = k.RemoveKey(2)
105	if err == nil {
106		t.Fatalf("err: %v", err)
107	}
108}
109
110func TestKeyring_MasterKey(t *testing.T) {
111	k := NewKeyring()
112	master := []byte("test")
113	master2 := []byte("test2")
114
115	// Check no master
116	out := k.MasterKey()
117	if out != nil {
118		t.Fatalf("bad: %v", out)
119	}
120
121	// Set master
122	k = k.SetMasterKey(master)
123	out = k.MasterKey()
124	if !bytes.Equal(out, master) {
125		t.Fatalf("bad: %v", out)
126	}
127
128	// Update master
129	k = k.SetMasterKey(master2)
130	out = k.MasterKey()
131	if !bytes.Equal(out, master2) {
132		t.Fatalf("bad: %v", out)
133	}
134}
135
136func TestKeyring_Serialize(t *testing.T) {
137	k := NewKeyring()
138	master := []byte("test")
139	k = k.SetMasterKey(master)
140
141	now := time.Now()
142	testKey := []byte("testing")
143	testSecond := []byte("second")
144	k, _ = k.AddKey(&Key{Term: 1, Version: 1, Value: testKey, InstallTime: now})
145	k, _ = k.AddKey(&Key{Term: 2, Version: 1, Value: testSecond, InstallTime: now})
146
147	buf, err := k.Serialize()
148	if err != nil {
149		t.Fatalf("err: %v", err)
150	}
151
152	k2, err := DeserializeKeyring(buf)
153	if err != nil {
154		t.Fatalf("err: %v", err)
155	}
156
157	out := k2.MasterKey()
158	if !bytes.Equal(out, master) {
159		t.Fatalf("bad: %v", out)
160	}
161
162	if k2.ActiveTerm() != k.ActiveTerm() {
163		t.Fatalf("Term mismatch")
164	}
165
166	var i uint32
167	for i = 1; i < k.ActiveTerm(); i++ {
168		key1 := k2.TermKey(i)
169		key2 := k.TermKey(i)
170		// Work around timezone bug due to DeepEqual using == for comparison
171		if !key1.InstallTime.Equal(key2.InstallTime) {
172			t.Fatalf("bad: key 1:\n%#v\nkey 2:\n%#v", key1, key2)
173		}
174		key1.InstallTime = key2.InstallTime
175		if !reflect.DeepEqual(key1, key2) {
176			t.Fatalf("bad: key 1:\n%#v\nkey 2:\n%#v", key1, key2)
177		}
178	}
179}
180
181func TestKey_Serialize(t *testing.T) {
182	k := &Key{
183		Term:        10,
184		Version:     1,
185		Value:       []byte("foobarbaz"),
186		InstallTime: time.Now(),
187	}
188
189	buf, err := k.Serialize()
190	if err != nil {
191		t.Fatalf("err: %v", err)
192	}
193
194	out, err := DeserializeKey(buf)
195	if err != nil {
196		t.Fatalf("err: %v", err)
197	}
198
199	// Work around timezone bug due to DeepEqual using == for comparison
200	if !k.InstallTime.Equal(out.InstallTime) {
201		t.Fatalf("bad: expected:\n%#v\nactual:\n%#v", k, out)
202	}
203	k.InstallTime = out.InstallTime
204
205	if !reflect.DeepEqual(k, out) {
206		t.Fatalf("bad: %#v", out)
207	}
208}
209