246 lines
6.1 KiB
Go
246 lines
6.1 KiB
Go
package encrypt
|
|
|
|
import (
|
|
"testing"
|
|
|
|
bifrost "github.com/maximhq/bifrost/core"
|
|
"github.com/maximhq/bifrost/core/schemas"
|
|
)
|
|
|
|
func TestEncryptDecrypt(t *testing.T) {
|
|
// Set a test encryption key
|
|
testKey := "test-encryption-key-for-testing-32bytes"
|
|
Init(testKey, bifrost.NewDefaultLogger(schemas.LogLevelInfo))
|
|
|
|
testCases := []struct {
|
|
name string
|
|
plaintext string
|
|
}{
|
|
{
|
|
name: "Simple text",
|
|
plaintext: "hello world",
|
|
},
|
|
{
|
|
name: "AWS Access Key",
|
|
plaintext: "AKIAIOSFODNN7EXAMPLE",
|
|
},
|
|
{
|
|
name: "AWS Secret Key",
|
|
plaintext: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
|
},
|
|
{
|
|
name: "Empty string",
|
|
plaintext: "",
|
|
},
|
|
{
|
|
name: "Special characters",
|
|
plaintext: "!@#$%^&*()_+-=[]{}|;':\",./<>?`~",
|
|
},
|
|
{
|
|
name: "Long text",
|
|
plaintext: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
// Encrypt
|
|
encrypted, err := Encrypt(tc.plaintext)
|
|
if err != nil {
|
|
t.Fatalf("Failed to encrypt: %v", err)
|
|
}
|
|
|
|
// For empty strings, encryption should return empty
|
|
if tc.plaintext == "" {
|
|
if encrypted != "" {
|
|
t.Errorf("Expected empty string for empty input, got: %s", encrypted)
|
|
}
|
|
return
|
|
}
|
|
|
|
// Encrypted text should be different from plaintext
|
|
if encrypted == tc.plaintext {
|
|
t.Errorf("Encrypted text should be different from plaintext")
|
|
}
|
|
|
|
// Decrypt
|
|
decrypted, err := Decrypt(encrypted)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decrypt: %v", err)
|
|
}
|
|
|
|
// Decrypted text should match original plaintext
|
|
if decrypted != tc.plaintext {
|
|
t.Errorf("Decrypted text does not match original.\nExpected: %s\nGot: %s", tc.plaintext, decrypted)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEncryptDeterminism(t *testing.T) {
|
|
// Set a test encryption key
|
|
testKey := "test-encryption-key-for-testing-32bytes"
|
|
Init(testKey, bifrost.NewDefaultLogger(schemas.LogLevelInfo))
|
|
|
|
plaintext := "test-plaintext"
|
|
|
|
// Encrypt the same text twice
|
|
encrypted1, err := Encrypt(plaintext)
|
|
if err != nil {
|
|
t.Fatalf("Failed to encrypt: %v", err)
|
|
}
|
|
encrypted2, err := Encrypt(plaintext)
|
|
if err != nil {
|
|
t.Fatalf("Failed to encrypt: %v", err)
|
|
}
|
|
|
|
// They should be different (due to random nonce)
|
|
if encrypted1 == encrypted2 {
|
|
t.Errorf("Two encryptions of the same plaintext should produce different ciphertexts (due to random nonce)")
|
|
}
|
|
|
|
// But both should decrypt to the same plaintext
|
|
decrypted1, err := Decrypt(encrypted1)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decrypt first: %v", err)
|
|
}
|
|
decrypted2, err := Decrypt(encrypted2)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decrypt second: %v", err)
|
|
}
|
|
|
|
if decrypted1 != plaintext || decrypted2 != plaintext {
|
|
t.Errorf("Both decryptions should match original plaintext")
|
|
}
|
|
}
|
|
|
|
func TestDecryptInvalidData(t *testing.T) {
|
|
// Set a test encryption key
|
|
testKey := "test-encryption-key-for-testing-32bytes"
|
|
Init(testKey, bifrost.NewDefaultLogger(schemas.LogLevelInfo))
|
|
|
|
testCases := []struct {
|
|
name string
|
|
ciphertext string
|
|
}{
|
|
{
|
|
name: "Invalid base64",
|
|
ciphertext: "not-valid-base64!@#$",
|
|
},
|
|
{
|
|
name: "Valid base64 but invalid ciphertext",
|
|
ciphertext: "YWJjZGVmZ2hpamtsbW5vcA==",
|
|
},
|
|
{
|
|
name: "Too short ciphertext",
|
|
ciphertext: "YWJj",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
_, err := Decrypt(tc.ciphertext)
|
|
if err == nil {
|
|
t.Errorf("Expected error when decrypting invalid data, got nil")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestKDFWithVariousKeyLengths(t *testing.T) {
|
|
// Test that keys of various lengths work correctly with KDF
|
|
testCases := []struct {
|
|
name string
|
|
key string
|
|
}{
|
|
{
|
|
name: "Short key (8 bytes)",
|
|
key: "shortkey",
|
|
},
|
|
{
|
|
name: "Medium key (16 bytes)",
|
|
key: "medium-key-16byt",
|
|
},
|
|
{
|
|
name: "Long key (32 bytes)",
|
|
key: "this-is-a-32-byte-long-key!!",
|
|
},
|
|
{
|
|
name: "Very long key (64 bytes)",
|
|
key: "this-is-a-very-long-key-that-is-definitely-more-than-64-bytes",
|
|
},
|
|
}
|
|
|
|
plaintext := "test-data-for-encryption"
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
// Initialize with this key
|
|
Init(tc.key, bifrost.NewDefaultLogger(schemas.LogLevelInfo))
|
|
|
|
// Encrypt
|
|
encrypted, err := Encrypt(plaintext)
|
|
if err != nil {
|
|
t.Fatalf("Failed to encrypt: %v", err)
|
|
}
|
|
|
|
// Should produce valid ciphertext
|
|
if encrypted == plaintext {
|
|
t.Errorf("Encrypted text should be different from plaintext")
|
|
}
|
|
|
|
// Decrypt should work
|
|
decrypted, err := Decrypt(encrypted)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decrypt with %s: %v", tc.name, err)
|
|
}
|
|
|
|
if decrypted != plaintext {
|
|
t.Errorf("Decrypted text does not match original.\nExpected: %s\nGot: %s", plaintext, decrypted)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestKDFDeterministic(t *testing.T) {
|
|
// Test that the same passphrase always produces the same derived key
|
|
passphrase := "test-passphrase"
|
|
plaintext := "test-data"
|
|
|
|
// Initialize with passphrase and encrypt
|
|
Init(passphrase, bifrost.NewDefaultLogger(schemas.LogLevelInfo))
|
|
encrypted1, err := Encrypt(plaintext)
|
|
if err != nil {
|
|
t.Fatalf("Failed to encrypt: %v", err)
|
|
}
|
|
|
|
// Re-initialize with same passphrase (simulating restart)
|
|
Init(passphrase, bifrost.NewDefaultLogger(schemas.LogLevelInfo))
|
|
|
|
// Should be able to decrypt the previously encrypted data
|
|
decrypted, err := Decrypt(encrypted1)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decrypt after re-initialization: %v", err)
|
|
}
|
|
|
|
if decrypted != plaintext {
|
|
t.Errorf("Decrypted text does not match original after re-initialization.\nExpected: %s\nGot: %s", plaintext, decrypted)
|
|
}
|
|
|
|
// Encrypt again with same passphrase
|
|
encrypted2, err := Encrypt(plaintext)
|
|
if err != nil {
|
|
t.Fatalf("Failed to encrypt: %v", err)
|
|
}
|
|
|
|
// Should be able to decrypt both (even though they're different due to nonce)
|
|
decrypted2, err := Decrypt(encrypted2)
|
|
if err != nil {
|
|
t.Fatalf("Failed to decrypt second encryption: %v", err)
|
|
}
|
|
|
|
if decrypted2 != plaintext {
|
|
t.Errorf("Second decryption does not match original.\nExpected: %s\nGot: %s", plaintext, decrypted2)
|
|
}
|
|
}
|