package vault import ( "strings" "testing" ) func TestDeriveKeyConsistent(t *testing.T) { salt := []byte("test-salt-exactly-32-bytes-long!") key1 := DeriveKey("mypassword", salt) key2 := DeriveKey("mypassword", salt) if len(key1) != 32 { t.Errorf("key length = %d, want 32", len(key1)) } if string(key1) != string(key2) { t.Error("same password+salt produced different keys") } } func TestDeriveKeyDifferentPasswords(t *testing.T) { salt := []byte("test-salt-exactly-32-bytes-long!") key1 := DeriveKey("password1", salt) key2 := DeriveKey("password2", salt) if string(key1) == string(key2) { t.Error("different passwords produced same key") } } func TestEncryptDecryptRoundTrip(t *testing.T) { key := DeriveKey("testpassword", []byte("test-salt-exactly-32-bytes-long!")) vs := NewVaultService(key) plaintext := "super-secret-ssh-key-data" encrypted, err := vs.Encrypt(plaintext) if err != nil { t.Fatalf("Encrypt() error: %v", err) } if !strings.HasPrefix(encrypted, "v1:") { t.Errorf("encrypted does not start with v1: prefix: %q", encrypted[:10]) } decrypted, err := vs.Decrypt(encrypted) if err != nil { t.Fatalf("Decrypt() error: %v", err) } if decrypted != plaintext { t.Errorf("Decrypt() = %q, want %q", decrypted, plaintext) } } func TestEncryptProducesDifferentCiphertexts(t *testing.T) { key := DeriveKey("testpassword", []byte("test-salt-exactly-32-bytes-long!")) vs := NewVaultService(key) enc1, _ := vs.Encrypt("same-data") enc2, _ := vs.Encrypt("same-data") if enc1 == enc2 { t.Error("two encryptions of same data produced identical ciphertext (IV reuse)") } } func TestDecryptWrongKey(t *testing.T) { key1 := DeriveKey("password1", []byte("test-salt-exactly-32-bytes-long!")) key2 := DeriveKey("password2", []byte("test-salt-exactly-32-bytes-long!")) vs1 := NewVaultService(key1) vs2 := NewVaultService(key2) encrypted, _ := vs1.Encrypt("secret") _, err := vs2.Decrypt(encrypted) if err == nil { t.Error("Decrypt() with wrong key should return error") } } func TestDecryptInvalidFormat(t *testing.T) { key := DeriveKey("test", []byte("test-salt-exactly-32-bytes-long!")) vs := NewVaultService(key) _, err := vs.Decrypt("not-valid-format") if err == nil { t.Error("Decrypt() with invalid format should return error") } } func TestGenerateSalt(t *testing.T) { salt1, err := GenerateSalt() if err != nil { t.Fatalf("GenerateSalt() error: %v", err) } if len(salt1) != 32 { t.Errorf("salt length = %d, want 32", len(salt1)) } salt2, _ := GenerateSalt() if string(salt1) == string(salt2) { t.Error("two calls to GenerateSalt produced identical salt") } }