Files
cryptomon/internal/auth/auth_test.go
T

82 lines
2.5 KiB
Go
Raw Normal View History

2026-08-25 06:37:14 +01:00
package auth
import (
"encoding/hex"
"testing"
"time"
)
// Known-answer test for the hand-rolled PBKDF2-HMAC-SHA256 core, so a typo
// in the loop (block index, XOR fold, etc.) fails loudly instead of just
// producing a hash that happens to round-trip against itself.
func TestPBKDF2Vector(t *testing.T) {
got := pbkdf2("password", []byte("salt"), 1, 32)
want, _ := hex.DecodeString("120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b")
if hex.EncodeToString(got) != hex.EncodeToString(want) {
t.Fatalf("pbkdf2(password,salt,1,32) = %x, want %x", got, want)
}
}
func TestHashAndVerifyPassword(t *testing.T) {
hash, err := HashPassword("correct horse battery staple")
if err != nil {
t.Fatal(err)
}
if !VerifyPassword("correct horse battery staple", hash) {
t.Fatal("VerifyPassword rejected the correct password")
}
if VerifyPassword("wrong password", hash) {
t.Fatal("VerifyPassword accepted the wrong password")
}
}
// RFC 4226 Appendix D HOTP test vectors (secret "12345678901234567890",
// 6-digit truncation) — TOTP is just HOTP with counter = unixtime/step, so
// this pins down the shared HMAC/truncation core.
func TestHOTPVectors(t *testing.T) {
secret := []byte("12345678901234567890")
want := []string{
"755224", "287082", "359152", "969429", "338314",
"254676", "287922", "162583", "399871", "520489",
}
for counter, code := range want {
got := hotp(secret, uint64(counter), 6)
if got != code {
t.Fatalf("hotp(counter=%d) = %s, want %s", counter, got, code)
}
}
}
func TestValidateTOTPRoundtrip(t *testing.T) {
secret, err := NewTOTPSecret()
if err != nil {
t.Fatal(err)
}
code, err := totpAt(secret, time.Now())
if err != nil {
t.Fatal(err)
}
if !ValidateTOTP(secret, code) {
t.Fatal("ValidateTOTP rejected a freshly generated code")
}
if ValidateTOTP(secret, "000000") {
t.Fatal("ValidateTOTP accepted an arbitrary wrong code")
}
}
func TestSessionTokenRoundtrip(t *testing.T) {
key := []byte("0123456789abcdef0123456789abcdef")
tok := NewSessionToken(key, "admin", 3, time.Hour)
user, version, ok := ParseSessionToken(key, tok)
if !ok || user != "admin" || version != 3 {
t.Fatalf("roundtrip failed: user=%q version=%d ok=%v", user, version, ok)
}
if _, _, ok := ParseSessionToken(key, tok+"tampered"); ok {
t.Fatal("ParseSessionToken accepted a tampered token")
}
otherKey := []byte("ffffffffffffffffffffffffffffffff")
if _, _, ok := ParseSessionToken(otherKey, tok); ok {
t.Fatal("ParseSessionToken accepted a token signed with a different key")
}
}