Add 'twofactor/' from commit 'c999bf35b0e47de4f63d59abbe0d7efc76c13ced'
git-subtree-dir: twofactor git-subtree-mainline:4dc135cfe0git-subtree-split:c999bf35b0
This commit is contained in:
87
twofactor/totp_test.go
Normal file
87
twofactor/totp_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package twofactor
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/benbjohnson/clock"
|
||||
)
|
||||
|
||||
var rfcTotpKey = map[crypto.Hash][]byte{
|
||||
crypto.SHA1: []byte("12345678901234567890"),
|
||||
crypto.SHA256: []byte("12345678901234567890123456789012"),
|
||||
crypto.SHA512: []byte("1234567890123456789012345678901234567890123456789012345678901234"),
|
||||
}
|
||||
var rfcTotpStep uint64 = 30
|
||||
|
||||
var rfcTotpTests = []struct {
|
||||
Time uint64
|
||||
Code string
|
||||
T uint64
|
||||
Algo crypto.Hash
|
||||
}{
|
||||
{59, "94287082", 1, crypto.SHA1},
|
||||
{59, "46119246", 1, crypto.SHA256},
|
||||
{59, "90693936", 1, crypto.SHA512},
|
||||
{1111111109, "07081804", 37037036, crypto.SHA1},
|
||||
{1111111109, "68084774", 37037036, crypto.SHA256},
|
||||
{1111111109, "25091201", 37037036, crypto.SHA512},
|
||||
{1111111111, "14050471", 37037037, crypto.SHA1},
|
||||
{1111111111, "67062674", 37037037, crypto.SHA256},
|
||||
{1111111111, "99943326", 37037037, crypto.SHA512},
|
||||
{1234567890, "89005924", 41152263, crypto.SHA1},
|
||||
{1234567890, "91819424", 41152263, crypto.SHA256},
|
||||
{1234567890, "93441116", 41152263, crypto.SHA512},
|
||||
{2000000000, "69279037", 66666666, crypto.SHA1},
|
||||
{2000000000, "90698825", 66666666, crypto.SHA256},
|
||||
{2000000000, "38618901", 66666666, crypto.SHA512},
|
||||
{20000000000, "65353130", 666666666, crypto.SHA1},
|
||||
{20000000000, "77737706", 666666666, crypto.SHA256},
|
||||
{20000000000, "47863826", 666666666, crypto.SHA512},
|
||||
}
|
||||
|
||||
func TestTotpRFC(t *testing.T) {
|
||||
for _, tc := range rfcTotpTests {
|
||||
otp := NewTOTP(rfcTotpKey[tc.Algo], 0, rfcTotpStep, 8, tc.Algo)
|
||||
if otp.otpCounter(tc.Time) != tc.T {
|
||||
fmt.Printf("twofactor: invalid TOTP (t=%d, h=%d)\n", tc.Time, tc.Algo)
|
||||
fmt.Printf("\texpected: %d\n", tc.T)
|
||||
fmt.Printf("\t actual: %d\n", otp.otpCounter(tc.Time))
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if code := otp.otp(otp.otpCounter(tc.Time)); code != tc.Code {
|
||||
fmt.Printf("twofactor: invalid TOTP (t=%d, h=%d)\n", tc.Time, tc.Algo)
|
||||
fmt.Printf("\texpected: %s\n", tc.Code)
|
||||
fmt.Printf("\t actual: %s\n", code)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTOTPTime(t *testing.T) {
|
||||
otp := GenerateGoogleTOTP()
|
||||
|
||||
testClock := clock.NewMock()
|
||||
testClock.Add(2 * time.Minute)
|
||||
SetClock(testClock)
|
||||
|
||||
code := otp.OTP()
|
||||
|
||||
testClock.Add(-1 * time.Minute)
|
||||
if newCode := otp.OTP(); newCode == code {
|
||||
t.Errorf("twofactor: TOTP: previous code %s shouldn't match code %s", newCode, code)
|
||||
}
|
||||
|
||||
testClock.Add(2 * time.Minute)
|
||||
if newCode := otp.OTP(); newCode == code {
|
||||
t.Errorf("twofactor: TOTP: future code %s shouldn't match code %s", newCode, code)
|
||||
}
|
||||
|
||||
testClock.Add(-1 * time.Minute)
|
||||
if newCode := otp.OTP(); newCode != code {
|
||||
t.Errorf("twofactor: TOTP: current code %s shouldn't match code %s", newCode, code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user