first commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user