Harden config perms and key derivation
CI / check-and-test (pull_request) Successful in 11s

Write generated configs 0600, treat new keys as raw AES-256, keep
PBKDF2 for unprefixed material, and cache derivation at startup.
This commit is contained in:
s1d3sw1ped_bot
2026-09-01 04:22:57 +00:00
parent 45778ac528
commit bc486eb49d
8 changed files with 293 additions and 52 deletions
+94
View File
@@ -1,6 +1,8 @@
package encryption
import (
"bytes"
"encoding/hex"
"testing"
"time"
)
@@ -240,3 +242,95 @@ func TestConstantTimeCompare(t *testing.T) {
t.Error("Empty slices should compare equal")
}
}
func TestResolveKeyRaw(t *testing.T) {
raw, err := GenerateRawKey()
if err != nil {
t.Fatalf("GenerateRawKey: %v", err)
}
if !IsRawKey(raw) {
t.Fatalf("generated key is not raw: %q", raw[:4])
}
key, err := ResolveKey(raw)
if err != nil {
t.Fatalf("ResolveKey raw: %v", err)
}
if len(key) != 32 {
t.Fatalf("raw key length %d", len(key))
}
decoded, err := hex.DecodeString(raw[len(RawKeyPrefix):])
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(key, decoded) {
t.Fatal("raw key was not hex-decoded as-is")
}
if bytes.Equal(key, DeriveKey(raw)) {
t.Fatal("raw key must not go through PBKDF2")
}
}
func TestResolveKeyLegacyHexStillPBKDF2(t *testing.T) {
legacy := "a0e3dd20a761b118ca234160dd8b87230a001e332a97c9cfe3b8b9c99efaae03"
decoded, err := hex.DecodeString(legacy)
if err != nil {
t.Fatal(err)
}
got, err := ResolveKey(legacy)
if err != nil {
t.Fatalf("ResolveKey legacy hex: %v", err)
}
want := DeriveKey(legacy)
if !bytes.Equal(got, want) {
t.Fatal("unprefixed 64-hex must still use PBKDF2 (old --generate-key configs)")
}
if bytes.Equal(got, decoded) {
t.Fatal("unprefixed 64-hex must not be treated as a raw AES key")
}
}
func TestResolveKeyPassphrase(t *testing.T) {
pw := "test-passphrase-not-a-hex-key-value"
got, err := ResolveKey(pw)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(got, DeriveKey(pw)) {
t.Fatal("passphrase should use PBKDF2")
}
}
func TestDeriveKeyCached(t *testing.T) {
pw := "cache-me-please-this-is-long-enough"
start := time.Now()
k1 := DeriveKey(pw)
first := time.Since(start)
start = time.Now()
k2 := DeriveKey(pw)
second := time.Since(start)
if !bytes.Equal(k1, k2) {
t.Fatal("cached key mismatch")
}
if first < 10*time.Millisecond {
t.Logf("first PBKDF2 unexpectedly fast: %v", first)
}
if second > 5*time.Millisecond {
t.Fatalf("cached DeriveKey too slow: first=%v second=%v", first, second)
}
}
func TestValidateRawEncryptionKey(t *testing.T) {
raw, err := GenerateRawKey()
if err != nil {
t.Fatal(err)
}
if err := ValidateEncryptionKey(raw); err != nil {
t.Fatalf("valid raw key rejected: %v", err)
}
if err := ValidateEncryptionKey("raw:not-hex"); err == nil {
t.Fatal("invalid raw hex should fail")
}
if err := ValidateEncryptionKey("raw:abcd"); err == nil {
t.Fatal("short raw key should fail")
}
}