Initial commit
This commit is contained in:
79
server/internal/security/security_test.go
Normal file
79
server/internal/security/security_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package security
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCipherRoundTripAndAADBinding(t *testing.T) {
|
||||
cipher, err := NewCipher(bytes.Repeat([]byte{1}, 32), bytes.Repeat([]byte{2}, 32))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ciphertext, nonce, err := cipher.Encrypt("+8613812345678", []byte("ticket:project-a:phone"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := cipher.Decrypt(ciphertext, nonce, []byte("ticket:project-a:phone"))
|
||||
if err != nil || got != "+8613812345678" {
|
||||
t.Fatalf("round trip got %q, %v", got, err)
|
||||
}
|
||||
if _, err := cipher.Decrypt(ciphertext, nonce, []byte("ticket:project-b:phone")); err == nil {
|
||||
t.Fatal("expected AAD mismatch to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCipherUsesUniqueNoncesAndStableHMAC(t *testing.T) {
|
||||
cipher, _ := NewCipher(bytes.Repeat([]byte{1}, 32), bytes.Repeat([]byte{2}, 32))
|
||||
one, nonceOne, _ := cipher.Encrypt("13812345678", nil)
|
||||
two, nonceTwo, _ := cipher.Encrypt("13812345678", nil)
|
||||
if bytes.Equal(nonceOne, nonceTwo) || bytes.Equal(one, two) {
|
||||
t.Fatal("expected randomized encryption")
|
||||
}
|
||||
if cipher.Digest("13812345678") != cipher.Digest("13812345678") {
|
||||
t.Fatal("expected stable HMAC digest")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizePhone(t *testing.T) {
|
||||
got, err := NormalizePhone("+86 (138) 1234-5678")
|
||||
if err != nil || got != "+8613812345678" {
|
||||
t.Fatalf("got %q, %v", got, err)
|
||||
}
|
||||
for _, invalid := range []string{"123", "+01234567", "138-ABC-0000", strings.Repeat("1", 16)} {
|
||||
if _, err := NormalizePhone(invalid); err == nil {
|
||||
t.Fatalf("expected %q to fail", invalid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenHasHighEntropyAndHashes(t *testing.T) {
|
||||
one, err := GenerateToken()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
two, _ := GenerateToken()
|
||||
if one == two || len(one) < 40 {
|
||||
t.Fatalf("unexpected tokens %q and %q", one, two)
|
||||
}
|
||||
if HashToken(one) == HashToken(two) || len(HashToken(one)) != 64 {
|
||||
t.Fatal("unexpected token hashes")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPasswordHash(t *testing.T) {
|
||||
hash, err := HashPassword("correct horse battery staple")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !VerifyPassword(hash, "correct horse battery staple") || VerifyPassword(hash, "wrong password") {
|
||||
t.Fatal("password verification mismatch")
|
||||
}
|
||||
if _, err := HashPassword("short"); err == nil {
|
||||
t.Fatal("expected short password rejection")
|
||||
}
|
||||
if _, err := HashPassword("XQK123456"); err != nil {
|
||||
t.Fatal("expected a nine-character password to satisfy the API policy")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user