Files
Charon/backend/internal/util/crypto_test.go
GitHub Actions 2dfe7ee241 feat: add additional security enhancements (Issue #365)
- Add constant-time token comparison utility (crypto/subtle)
- Add SBOM generation and attestation to CI/CD pipeline
- Document TLS enforcement, DNS security (DoH/DoT), and container hardening
- Create Security Incident Response Plan (SIRP)
- Add security update notification documentation

Security enhancements:
- Mitigates timing attacks on invite token validation
- Provides supply chain transparency with CycloneDX SBOM
- Documents production container hardening (read_only, cap_drop)

Closes #365
2025-12-21 19:00:29 +00:00

83 lines
2.2 KiB
Go

package util
import (
"testing"
)
func TestConstantTimeCompare(t *testing.T) {
tests := []struct {
name string
a string
b string
expected bool
}{
{"equal strings", "secret123", "secret123", true},
{"different strings", "secret123", "secret456", false},
{"different lengths", "short", "muchlonger", false},
{"empty strings", "", "", true},
{"one empty", "notempty", "", false},
{"unicode equal", "héllo", "héllo", true},
{"unicode different", "héllo", "hëllo", false},
{"special chars equal", "!@#$%^&*()", "!@#$%^&*()", true},
{"whitespace matters", "hello ", "hello", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ConstantTimeCompare(tt.a, tt.b)
if result != tt.expected {
t.Errorf("ConstantTimeCompare(%q, %q) = %v, want %v", tt.a, tt.b, result, tt.expected)
}
})
}
}
func TestConstantTimeCompareBytes(t *testing.T) {
tests := []struct {
name string
a []byte
b []byte
expected bool
}{
{"equal bytes", []byte{1, 2, 3}, []byte{1, 2, 3}, true},
{"different bytes", []byte{1, 2, 3}, []byte{1, 2, 4}, false},
{"different lengths", []byte{1, 2}, []byte{1, 2, 3}, false},
{"empty slices", []byte{}, []byte{}, true},
{"nil slices", nil, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ConstantTimeCompareBytes(tt.a, tt.b)
if result != tt.expected {
t.Errorf("ConstantTimeCompareBytes(%v, %v) = %v, want %v", tt.a, tt.b, result, tt.expected)
}
})
}
}
// BenchmarkConstantTimeCompare ensures the function remains constant-time.
func BenchmarkConstantTimeCompare(b *testing.B) {
secret := "a]3kL9#mP2$vN7@qR5*wX1&yT4^uI8%oE0!"
b.Run("equal", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ConstantTimeCompare(secret, secret)
}
})
b.Run("different_first_char", func(b *testing.B) {
different := "b]3kL9#mP2$vN7@qR5*wX1&yT4^uI8%oE0!"
for i := 0; i < b.N; i++ {
ConstantTimeCompare(secret, different)
}
})
b.Run("different_last_char", func(b *testing.B) {
different := "a]3kL9#mP2$vN7@qR5*wX1&yT4^uI8%oE0?"
for i := 0; i < b.N; i++ {
ConstantTimeCompare(secret, different)
}
})
}