feat(store): envelope DEK with admin/agent wrap slots
Open() now opens LOCKED; InitKeys generates a DEK sealed under both KEKs; Unlock loads it from the role's slot (admin slot has no agent fallback). s.key becomes the DEK, so account/mail crypto is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,29 +5,25 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testKey() []byte {
|
||||
k := make([]byte, 32)
|
||||
for i := range k {
|
||||
k[i] = byte(i)
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
// openTemp opens a fresh store in a temp dir.
|
||||
// openTemp opens a fresh store in a temp dir and initialises keys so that
|
||||
// account tests (which do crypto) work without needing their own setup.
|
||||
func openTemp(t *testing.T) *Store {
|
||||
t.Helper()
|
||||
p := filepath.Join(t.TempDir(), "emcli.db")
|
||||
s, err := Open(p, testKey())
|
||||
s, err := Open(p)
|
||||
if err != nil {
|
||||
t.Fatalf("Open: %v", err)
|
||||
}
|
||||
if err := s.InitKeys(k(0xAA), k(0xBB)); err != nil {
|
||||
t.Fatalf("InitKeys: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { s.Close() })
|
||||
return s
|
||||
}
|
||||
|
||||
func TestOpenCreatesSchemaAndIsIdempotent(t *testing.T) {
|
||||
p := filepath.Join(t.TempDir(), "emcli.db")
|
||||
s, err := Open(p, testKey())
|
||||
s, err := Open(p)
|
||||
if err != nil {
|
||||
t.Fatalf("first Open: %v", err)
|
||||
}
|
||||
@@ -38,7 +34,7 @@ func TestOpenCreatesSchemaAndIsIdempotent(t *testing.T) {
|
||||
s.Close()
|
||||
|
||||
// Re-open: must not error or duplicate.
|
||||
s2, err := Open(p, testKey())
|
||||
s2, err := Open(p)
|
||||
if err != nil {
|
||||
t.Fatalf("second Open: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user