Skip to content

Commit e336b72

Browse files
authored
Merge pull request #2 from CryptoLabInc/couragehong/fix/keys-exist-respects-parts
fix(keys): KeysExist must respect WithKeyParts
2 parents 171f75b + 177e903 commit e336b72

2 files changed

Lines changed: 53 additions & 6 deletions

File tree

keys.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,19 @@ func KeysExist(opts ...KeysOption) bool {
118118
if o.Path == "" {
119119
return false
120120
}
121-
slots := [3][2]string{
122-
{encKeyBinFile, encKeyJSONFile},
123-
{evalKeyBinFile, evalKeyJSONFile},
124-
{secKeyBinFile, secKeyJSONFile},
121+
wantEnc, wantEval, wantSec := resolveKeyParts(o.Parts)
122+
if wantEnc {
123+
if _, _, ok := resolveKeySlot(o.Path, encKeyBinFile, encKeyJSONFile); !ok {
124+
return false
125+
}
125126
}
126-
for _, s := range slots {
127-
if _, _, ok := resolveKeySlot(o.Path, s[0], s[1]); !ok {
127+
if wantEval {
128+
if _, _, ok := resolveKeySlot(o.Path, evalKeyBinFile, evalKeyJSONFile); !ok {
129+
return false
130+
}
131+
}
132+
if wantSec {
133+
if _, _, ok := resolveKeySlot(o.Path, secKeyBinFile, secKeyJSONFile); !ok {
128134
return false
129135
}
130136
}

keys_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,44 @@ func TestRegisterKeys_WithoutEvalPart_ReturnsErr(t *testing.T) {
320320
t.Errorf("ActivateKeys without KeyPartEval: got %v, want ErrKeysNotForRegister", err)
321321
}
322322
}
323+
324+
// TestKeysExist_PartsAware exercises the KeyParts-aware lookup. Vault's
325+
// agent-manifest delivery only ships EncKey to the client (Eval/Sec stay
326+
// in Vault), so the consumer opens that directory with
327+
// WithKeyParts(KeyPartEnc) and expects KeysExist to return true on an
328+
// Enc-only directory. The previous implementation walked all three slots
329+
// unconditionally and rejected the bundle.
330+
func TestKeysExist_PartsAware(t *testing.T) {
331+
encOnly := func(t *testing.T) string {
332+
t.Helper()
333+
dir := t.TempDir()
334+
if err := os.WriteFile(filepath.Join(dir, encKeyJSONFile), []byte("{}"), 0o600); err != nil {
335+
t.Fatal(err)
336+
}
337+
return dir
338+
}
339+
340+
t.Run("enc-only dir + WithKeyParts(KeyPartEnc) → true", func(t *testing.T) {
341+
dir := encOnly(t)
342+
opts := append(baseKeyOpts(dir), WithKeyParts(KeyPartEnc))
343+
if !KeysExist(opts...) {
344+
t.Error("KeysExist with KeyPartEnc must accept Enc-only directory")
345+
}
346+
})
347+
348+
t.Run("enc-only dir + default parts (= all three) → false", func(t *testing.T) {
349+
dir := encOnly(t)
350+
// No WithKeyParts → resolveKeyParts treats it as all three required.
351+
if KeysExist(baseKeyOpts(dir)...) {
352+
t.Error("default parts must require all 3 slots")
353+
}
354+
})
355+
356+
t.Run("enc-only dir + WithKeyParts(KeyPartEval) → false (eval missing)", func(t *testing.T) {
357+
dir := encOnly(t)
358+
opts := append(baseKeyOpts(dir), WithKeyParts(KeyPartEval))
359+
if KeysExist(opts...) {
360+
t.Error("requesting Eval on an Enc-only dir must fail")
361+
}
362+
})
363+
}

0 commit comments

Comments
 (0)