1package vault
2
3import (
4	"encoding/base64"
5	"testing"
6
7	"github.com/hashicorp/vault/helper/namespace"
8	"github.com/hashicorp/vault/helper/pgpkeys"
9	"github.com/hashicorp/vault/helper/xor"
10	"github.com/hashicorp/vault/sdk/helper/base62"
11)
12
13func TestCore_GenerateRoot_Lifecycle(t *testing.T) {
14	c, masterKeys, _ := TestCoreUnsealed(t)
15	testCore_GenerateRoot_Lifecycle_Common(t, c, masterKeys)
16}
17
18func testCore_GenerateRoot_Lifecycle_Common(t *testing.T, c *Core, keys [][]byte) {
19	// Verify update not allowed
20	if _, err := c.GenerateRootUpdate(namespace.RootContext(nil), keys[0], "", GenerateStandardRootTokenStrategy); err == nil {
21		t.Fatalf("no root generation in progress")
22	}
23
24	// Should be no progress
25	num, err := c.GenerateRootProgress()
26	if err != nil {
27		t.Fatalf("err: %v", err)
28	}
29	if num != 0 {
30		t.Fatalf("bad: %d", num)
31	}
32
33	// Should be no config
34	conf, err := c.GenerateRootConfiguration()
35	if err != nil {
36		t.Fatalf("err: %v", err)
37	}
38	if conf != nil {
39		t.Fatalf("bad: %v", conf)
40	}
41
42	// Cancel should be idempotent
43	err = c.GenerateRootCancel()
44	if err != nil {
45		t.Fatalf("err: %v", err)
46	}
47
48	otp, err := base62.Random(26)
49	if err != nil {
50		t.Fatal(err)
51	}
52
53	// Start a root generation
54	err = c.GenerateRootInit(otp, "", GenerateStandardRootTokenStrategy)
55	if err != nil {
56		t.Fatalf("err: %v", err)
57	}
58
59	// Should get config
60	conf, err = c.GenerateRootConfiguration()
61	if err != nil {
62		t.Fatalf("err: %v", err)
63	}
64
65	// Cancel should be clear
66	err = c.GenerateRootCancel()
67	if err != nil {
68		t.Fatalf("err: %v", err)
69	}
70
71	// Should be no config
72	conf, err = c.GenerateRootConfiguration()
73	if err != nil {
74		t.Fatalf("err: %v", err)
75	}
76	if conf != nil {
77		t.Fatalf("bad: %v", conf)
78	}
79}
80
81func TestCore_GenerateRoot_Init(t *testing.T) {
82	c, _, _ := TestCoreUnsealed(t)
83	testCore_GenerateRoot_Init_Common(t, c)
84
85	bc := &SealConfig{SecretShares: 5, SecretThreshold: 3, StoredShares: 1}
86	rc := &SealConfig{SecretShares: 5, SecretThreshold: 3}
87	c, _, _, _ = TestCoreUnsealedWithConfigs(t, bc, rc)
88	testCore_GenerateRoot_Init_Common(t, c)
89}
90
91func testCore_GenerateRoot_Init_Common(t *testing.T, c *Core) {
92	otp, err := base62.Random(26)
93	if err != nil {
94		t.Fatal(err)
95	}
96
97	err = c.GenerateRootInit(otp, "", GenerateStandardRootTokenStrategy)
98	if err != nil {
99		t.Fatalf("err: %v", err)
100	}
101
102	// Second should fail
103	err = c.GenerateRootInit("", pgpkeys.TestPubKey1, GenerateStandardRootTokenStrategy)
104	if err == nil {
105		t.Fatalf("should fail")
106	}
107}
108
109func TestCore_GenerateRoot_InvalidMasterNonce(t *testing.T) {
110	c, masterKeys, _ := TestCoreUnsealed(t)
111	// Pass in master keys as they'll be invalid
112	masterKeys[0][0]++
113	testCore_GenerateRoot_InvalidMasterNonce_Common(t, c, masterKeys)
114}
115
116func testCore_GenerateRoot_InvalidMasterNonce_Common(t *testing.T, c *Core, keys [][]byte) {
117	otp, err := base62.Random(26)
118	if err != nil {
119		t.Fatal(err)
120	}
121
122	err = c.GenerateRootInit(otp, "", GenerateStandardRootTokenStrategy)
123	if err != nil {
124		t.Fatalf("err: %v", err)
125	}
126
127	// Fetch new config with generated nonce
128	rgconf, err := c.GenerateRootConfiguration()
129	if err != nil {
130		t.Fatalf("err: %v", err)
131	}
132	if rgconf == nil {
133		t.Fatalf("bad: no rekey config received")
134	}
135
136	// Provide the nonce (invalid)
137	_, err = c.GenerateRootUpdate(namespace.RootContext(nil), keys[0], "abcd", GenerateStandardRootTokenStrategy)
138	if err == nil {
139		t.Fatalf("expected error")
140	}
141
142	// Provide the master (invalid)
143	for _, key := range keys {
144		_, err = c.GenerateRootUpdate(namespace.RootContext(nil), key, rgconf.Nonce, GenerateStandardRootTokenStrategy)
145	}
146	if err == nil {
147		t.Fatalf("expected error")
148	}
149}
150
151func TestCore_GenerateRoot_Update_OTP(t *testing.T) {
152	c, masterKeys, _ := TestCoreUnsealed(t)
153	testCore_GenerateRoot_Update_OTP_Common(t, c, masterKeys)
154}
155
156func testCore_GenerateRoot_Update_OTP_Common(t *testing.T, c *Core, keys [][]byte) {
157	otp, err := base62.Random(26)
158	if err != nil {
159		t.Fatal(err)
160	}
161
162	// Start a root generation
163	err = c.GenerateRootInit(otp, "", GenerateStandardRootTokenStrategy)
164	if err != nil {
165		t.Fatal(err)
166	}
167
168	// Fetch new config with generated nonce
169	rkconf, err := c.GenerateRootConfiguration()
170	if err != nil {
171		t.Fatalf("err: %v", err)
172	}
173	if rkconf == nil {
174		t.Fatalf("bad: no root generation config received")
175	}
176
177	// Provide the keys
178	var result *GenerateRootResult
179	for _, key := range keys {
180		result, err = c.GenerateRootUpdate(namespace.RootContext(nil), key, rkconf.Nonce, GenerateStandardRootTokenStrategy)
181		if err != nil {
182			t.Fatalf("err: %v", err)
183		}
184		if result.EncodedToken != "" {
185			break
186		}
187	}
188	if result == nil {
189		t.Fatalf("Bad, result is nil")
190	}
191
192	encodedToken := result.EncodedToken
193
194	// Should be no progress
195	num, err := c.GenerateRootProgress()
196	if err != nil {
197		t.Fatalf("err: %v", err)
198	}
199	if num != 0 {
200		t.Fatalf("bad: %d", num)
201	}
202
203	// Should be no config
204	conf, err := c.GenerateRootConfiguration()
205	if err != nil {
206		t.Fatalf("err: %v", err)
207	}
208	if conf != nil {
209		t.Fatalf("bad: %v", conf)
210	}
211
212	tokenBytes, err := base64.RawStdEncoding.DecodeString(encodedToken)
213	if err != nil {
214		t.Fatal(err)
215	}
216
217	tokenBytes, err = xor.XORBytes(tokenBytes, []byte(otp))
218	if err != nil {
219		t.Fatal(err)
220	}
221
222	token := string(tokenBytes)
223
224	// Ensure that the token is a root token
225	te, err := c.tokenStore.Lookup(namespace.RootContext(nil), token)
226	if err != nil {
227		t.Fatalf("err: %v", err)
228	}
229	if te == nil {
230		t.Fatalf("token was nil")
231	}
232	if te.ID != token || te.Parent != "" ||
233		len(te.Policies) != 1 || te.Policies[0] != "root" {
234		t.Fatalf("bad: %#v", *te)
235	}
236}
237
238func TestCore_GenerateRoot_Update_PGP(t *testing.T) {
239	c, masterKeys, _ := TestCoreUnsealed(t)
240	testCore_GenerateRoot_Update_PGP_Common(t, c, masterKeys)
241}
242
243func testCore_GenerateRoot_Update_PGP_Common(t *testing.T, c *Core, keys [][]byte) {
244	// Start a root generation
245	err := c.GenerateRootInit("", pgpkeys.TestPubKey1, GenerateStandardRootTokenStrategy)
246	if err != nil {
247		t.Fatalf("err: %v", err)
248	}
249
250	// Fetch new config with generated nonce
251	rkconf, err := c.GenerateRootConfiguration()
252	if err != nil {
253		t.Fatalf("err: %v", err)
254	}
255	if rkconf == nil {
256		t.Fatalf("bad: no root generation config received")
257	}
258
259	// Provide the keys
260	var result *GenerateRootResult
261	for _, key := range keys {
262		result, err = c.GenerateRootUpdate(namespace.RootContext(nil), key, rkconf.Nonce, GenerateStandardRootTokenStrategy)
263		if err != nil {
264			t.Fatalf("err: %v", err)
265		}
266		if result.EncodedToken != "" {
267			break
268		}
269	}
270	if result == nil {
271		t.Fatalf("Bad, result is nil")
272	}
273
274	encodedToken := result.EncodedToken
275
276	// Should be no progress
277	num, err := c.GenerateRootProgress()
278	if err != nil {
279		t.Fatalf("err: %v", err)
280	}
281	if num != 0 {
282		t.Fatalf("bad: %d", num)
283	}
284
285	// Should be no config
286	conf, err := c.GenerateRootConfiguration()
287	if err != nil {
288		t.Fatalf("err: %v", err)
289	}
290	if conf != nil {
291		t.Fatalf("bad: %v", conf)
292	}
293
294	ptBuf, err := pgpkeys.DecryptBytes(encodedToken, pgpkeys.TestPrivKey1)
295	if err != nil {
296		t.Fatal(err)
297	}
298	if ptBuf == nil {
299		t.Fatal("Got nil plaintext key")
300	}
301
302	token := ptBuf.String()
303
304	// Ensure that the token is a root token
305	te, err := c.tokenStore.Lookup(namespace.RootContext(nil), token)
306	if err != nil {
307		t.Fatalf("err: %v", err)
308	}
309	if te == nil {
310		t.Fatalf("token was nil")
311	}
312	if te.ID != token || te.Parent != "" ||
313		len(te.Policies) != 1 || te.Policies[0] != "root" {
314		t.Fatalf("bad: %#v", *te)
315	}
316}
317