80 lines
2.3 KiB
Go
80 lines
2.3 KiB
Go
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")
|
|
}
|
|
}
|