summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2022-08-06 23:07:28 +0700
committerShulhan <ms@kilabit.info>2022-08-06 23:07:33 +0700
commit0bb0c3cc265565a7abd2d2cd84e7f3865f5777f3 (patch)
tree300d76e662149fac17f4cdfa2bab7862c378b475
parent055802ca21d6c1e8c8427bd9553a821fbb7ef721 (diff)
downloadpakakeh.go-0bb0c3cc265565a7abd2d2cd84e7f3865f5777f3.tar.xz
lib/totp: cleaning up the codes
This changes replace ":=" with explicit variable declarations and use raw string literal whenever possible.
-rw-r--r--lib/totp/totp.go90
-rw-r--r--lib/totp/totp_example_test.go25
-rw-r--r--lib/totp/totp_test.go199
3 files changed, 196 insertions, 118 deletions
diff --git a/lib/totp/totp.go b/lib/totp/totp.go
index 7c3d1ce0..03dfb401 100644
--- a/lib/totp/totp.go
+++ b/lib/totp/totp.go
@@ -89,21 +89,30 @@ func New(cryptoHash CryptoHash, codeDigits, timeStep int) Protocol {
// Generate one time password using the secret and current timestamp.
func (p *Protocol) Generate(secret []byte) (otp string, err error) {
- mac := hmac.New(p.fnHash, secret)
- now := time.Now().Unix()
+ var (
+ mac hash.Hash = hmac.New(p.fnHash, secret)
+ now int64 = time.Now().Unix()
+ )
+
return p.generateWithTimestamp(mac, now)
}
// GenerateN generate n number of passwords from (current time - N*timeStep)
// until the curent time.
func (p *Protocol) GenerateN(secret []byte, n int) (listOTP []string, err error) {
- mac := hmac.New(p.fnHash, secret)
- ts := time.Now().Unix()
- for x := 0; x < n; x++ {
- t := ts - int64(x*p.timeStep)
- otp, err := p.generateWithTimestamp(mac, t)
+ var (
+ mac hash.Hash = hmac.New(p.fnHash, secret)
+ ts int64 = time.Now().Unix()
+
+ otp string
+ t int64
+ x int
+ )
+ for x = 0; x < n; x++ {
+ t = ts - int64(x*p.timeStep)
+ otp, err = p.generateWithTimestamp(mac, t)
if err != nil {
- return nil, fmt.Errorf("GenerateN: %w", err)
+ return nil, fmt.Errorf(`GenerateN: %w`, err)
}
listOTP = append(listOTP, otp)
}
@@ -122,22 +131,30 @@ func (p *Protocol) GenerateN(secret []byte, n int) (listOTP []string, err error)
//
// For security reason, the maximum stepsBack is limited to DefStepsBack.
func (p *Protocol) Verify(secret []byte, token string, stepsBack int) bool {
- mac := hmac.New(p.fnHash, secret)
- now := time.Now().Unix()
+ var (
+ mac hash.Hash = hmac.New(p.fnHash, secret)
+ now int64 = time.Now().Unix()
+ )
+
if stepsBack <= 0 || stepsBack > DefStepsBack {
stepsBack = DefStepsBack
}
return p.verifyWithTimestamp(mac, token, stepsBack, now)
}
-func (p *Protocol) verifyWithTimestamp(
- mac hash.Hash, token string, steps int, ts int64,
-) bool {
- for x := 0; x < steps; x++ {
- t := ts - int64(x*p.timeStep)
- otp, err := p.generateWithTimestamp(mac, t)
+func (p *Protocol) verifyWithTimestamp(mac hash.Hash, token string, steps int, ts int64) bool {
+ var (
+ otp string
+ err error
+ t int64
+ x int
+ )
+
+ for x = 0; x < steps; x++ {
+ t = ts - int64(x*p.timeStep)
+ otp, err = p.generateWithTimestamp(mac, t)
if err != nil {
- log.Printf("Verify %d: %s", t, err.Error())
+ log.Printf(`Verify %d: %s`, t, err.Error())
continue
}
if otp == token {
@@ -147,33 +164,38 @@ func (p *Protocol) verifyWithTimestamp(
return false
}
-func (p *Protocol) generateWithTimestamp(mac hash.Hash, time int64) (
- otp string, err error,
-) {
- steps := int64((float64(time) / float64(p.timeStep)))
+func (p *Protocol) generateWithTimestamp(mac hash.Hash, time int64) (otp string, err error) {
+ var (
+ steps = int64((float64(time) / float64(p.timeStep)))
+ msg = fmt.Sprintf(`%016X`, steps)
+
+ fmtZeroPadding string
+ binary int
+ vbytes []byte
+ offset byte
+ )
- msg := fmt.Sprintf("%016X", steps)
- msgb, err := hex.DecodeString(msg)
+ vbytes, err = hex.DecodeString(msg)
if err != nil {
- return "", err
+ return ``, err
}
mac.Reset()
- _, _ = mac.Write(msgb)
- hash := mac.Sum(nil)
+ _, _ = mac.Write(vbytes)
+ vbytes = mac.Sum(nil)
- offset := hash[len(hash)-1] & 0xf
+ offset = vbytes[len(vbytes)-1] & 0xf
- var binary int = int(hash[offset]&0x7f) << 24
- binary |= int(hash[offset+1]&0xff) << 16
- binary |= int(hash[offset+2]&0xff) << 8
- binary |= int(hash[offset+3] & 0xff)
+ binary = int(vbytes[offset]&0x7f) << 24
+ binary |= int(vbytes[offset+1]&0xff) << 16
+ binary |= int(vbytes[offset+2]&0xff) << 8
+ binary |= int(vbytes[offset+3] & 0xff)
- otpb := binary % _digitsPower[p.codeDigits]
+ binary = binary % _digitsPower[p.codeDigits]
- fmtZeroPadding := fmt.Sprintf("%%0%dd", p.codeDigits)
+ fmtZeroPadding = fmt.Sprintf(`%%0%dd`, p.codeDigits)
- otp = fmt.Sprintf(fmtZeroPadding, otpb)
+ otp = fmt.Sprintf(fmtZeroPadding, binary)
return otp, nil
}
diff --git a/lib/totp/totp_example_test.go b/lib/totp/totp_example_test.go
index 7e40ea01..7958e6d0 100644
--- a/lib/totp/totp_example_test.go
+++ b/lib/totp/totp_example_test.go
@@ -11,21 +11,28 @@ import (
)
func ExampleProtocol_Verify() {
- secretHex := "3132333435363738393031323334353637383930"
+ var (
+ secretHex = `3132333435363738393031323334353637383930`
+ proto = New(CryptoHashSHA1, DefCodeDigits, DefTimeStep)
- secret, err := hex.DecodeString(secretHex)
+ otp string
+ err error
+ secret []byte
+ )
+
+ secret, err = hex.DecodeString(secretHex)
if err != nil {
log.Fatal(err)
}
- p := New(CryptoHashSHA1, DefCodeDigits, DefTimeStep)
- otp, _ := p.Generate(secret)
+ otp, _ = proto.Generate(secret)
- if p.Verify(secret, otp, 1) {
- fmt.Printf("Generated token is valid.\n")
+ if proto.Verify(secret, otp, 1) {
+ fmt.Println(`Generated token is valid.`)
} else {
- fmt.Printf("Generated token is not valid.\n")
+ fmt.Printf(`Generated token is not valid.`)
}
- //Output:
- //Generated token is valid.
+
+ // Output:
+ // Generated token is valid.
}
diff --git a/lib/totp/totp_test.go b/lib/totp/totp_test.go
index a15c68e1..9f42899a 100644
--- a/lib/totp/totp_test.go
+++ b/lib/totp/totp_test.go
@@ -10,189 +10,238 @@ import (
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
+ "hash"
"testing"
"github.com/shuLhan/share/lib/test"
)
func TestProtocol_generateWithTimestamp_sha1(t *testing.T) {
- secretHex := "3132333435363738393031323334353637383930"
+ type testCase struct {
+ exp string
+ time int64
+ }
+
+ var (
+ secretHex = `3132333435363738393031323334353637383930`
+ proto = New(CryptoHashSHA1, 8, DefTimeStep)
+
+ secretb []byte
+ err error
+ mac hash.Hash
+ )
- secretb, err := hex.DecodeString(secretHex)
+ secretb, err = hex.DecodeString(secretHex)
if err != nil {
t.Fatal(err)
}
- mac := hmac.New(sha1.New, secretb)
- p := New(CryptoHashSHA1, 8, DefTimeStep)
+ mac = hmac.New(sha1.New, secretb)
- cases := []struct {
- time int64
- exp string
- }{{
+ var cases = []testCase{{
time: 59,
- exp: "94287082",
+ exp: `94287082`,
}, {
time: 1111111109,
- exp: "07081804",
+ exp: `07081804`,
}, {
time: 1111111111,
- exp: "14050471",
+ exp: `14050471`,
}, {
time: 1234567890,
- exp: "89005924",
+ exp: `89005924`,
}, {
time: 2000000000,
- exp: "69279037",
+ exp: `69279037`,
}, {
time: 20000000000,
- exp: "65353130",
+ exp: `65353130`,
}}
- for _, c := range cases {
+ var (
+ c testCase
+ got string
+ )
+ for _, c = range cases {
mac.Reset()
- got, err := p.generateWithTimestamp(mac, c.time)
+ got, err = proto.generateWithTimestamp(mac, c.time)
if err != nil {
t.Error(err)
continue
}
- test.Assert(t, "generateWithTimestamp", c.exp, got)
+ test.Assert(t, `generateWithTimestamp`, c.exp, got)
}
}
func TestProtocol_generateWithTimestamp_sha256(t *testing.T) {
- secretHex := "3132333435363738393031323334353637383930" +
- "313233343536373839303132"
+ type testCase struct {
+ exp string
+ time int64
+ }
- secretb, err := hex.DecodeString(secretHex)
+ var (
+ secretHex = `3132333435363738393031323334353637383930313233343536373839303132`
+ proto = New(CryptoHashSHA256, 8, DefTimeStep)
+
+ mac hash.Hash
+ secretb []byte
+ err error
+ )
+
+ secretb, err = hex.DecodeString(secretHex)
if err != nil {
t.Fatal(err)
}
- mac := hmac.New(sha256.New, secretb)
- p := New(CryptoHashSHA256, 8, DefTimeStep)
+ mac = hmac.New(sha256.New, secretb)
- cases := []struct {
- time int64
- exp string
- }{{
+ var cases = []testCase{{
time: 59,
- exp: "46119246",
+ exp: `46119246`,
}, {
time: 1111111109,
- exp: "68084774",
+ exp: `68084774`,
}, {
time: 1111111111,
- exp: "67062674",
+ exp: `67062674`,
}, {
time: 1234567890,
- exp: "91819424",
+ exp: `91819424`,
}, {
time: 2000000000,
- exp: "90698825",
+ exp: `90698825`,
}, {
time: 20000000000,
- exp: "77737706",
+ exp: `77737706`,
}}
- for _, c := range cases {
+ var (
+ c testCase
+ got string
+ )
+ for _, c = range cases {
mac.Reset()
- got, err := p.generateWithTimestamp(mac, c.time)
+ got, err = proto.generateWithTimestamp(mac, c.time)
if err != nil {
t.Error(err)
continue
}
- test.Assert(t, "generateWithTimestamp", c.exp, got)
+ test.Assert(t, `generateWithTimestamp`, c.exp, got)
}
}
func TestProtocol_generateWithTimestamp_sha512(t *testing.T) {
- secretHex := "3132333435363738393031323334353637383930" +
- "3132333435363738393031323334353637383930" +
- "3132333435363738393031323334353637383930" +
- "31323334"
+ type testCase struct {
+ exp string
+ time int64
+ }
+
+ var (
+ secretHex = `3132333435363738393031323334353637383930` +
+ `3132333435363738393031323334353637383930` +
+ `3132333435363738393031323334353637383930` +
+ `31323334`
+ proto = New(CryptoHashSHA512, 8, DefTimeStep)
+
+ mac hash.Hash
+ secretb []byte
+ err error
+ )
- secretb, err := hex.DecodeString(secretHex)
+ secretb, err = hex.DecodeString(secretHex)
if err != nil {
t.Fatal(err)
}
- cases := []struct {
- time int64
- exp string
- }{{
+ mac = hmac.New(sha512.New, secretb)
+
+ var cases = []testCase{{
time: 59,
- exp: "90693936",
+ exp: `90693936`,
}, {
time: 1111111109,
- exp: "25091201",
+ exp: `25091201`,
}, {
time: 1111111111,
- exp: "99943326",
+ exp: `99943326`,
}, {
time: 1234567890,
- exp: "93441116",
+ exp: `93441116`,
}, {
time: 2000000000,
- exp: "38618901",
+ exp: `38618901`,
}, {
time: 20000000000,
- exp: "47863826",
+ exp: `47863826`,
}}
- p := New(CryptoHashSHA512, 8, DefTimeStep)
- mac := hmac.New(sha512.New, secretb)
-
- for _, c := range cases {
+ var (
+ c testCase
+ got string
+ )
+ for _, c = range cases {
mac.Reset()
- got, err := p.generateWithTimestamp(mac, c.time)
+ got, err = proto.generateWithTimestamp(mac, c.time)
if err != nil {
t.Error(err)
continue
}
- test.Assert(t, "generateWithTimestamp sha512", c.exp, got)
+ test.Assert(t, `generateWithTimestamp sha512`, c.exp, got)
}
}
func TestProtocol_verifyWithTimestamp(t *testing.T) {
- secretHex := "3132333435363738393031323334353637383930"
+ type testCase struct {
+ desc string
+ token string
+ ts int64
+ steps int
+ exp bool
+ }
+
+ var (
+ secretHex = `3132333435363738393031323334353637383930`
+ proto = New(CryptoHashSHA1, 8, DefTimeStep)
+
+ mac hash.Hash
+ secretb []byte
+ err error
+ )
- secretb, err := hex.DecodeString(secretHex)
+ secretb, err = hex.DecodeString(secretHex)
if err != nil {
t.Fatal(err)
}
- mac := hmac.New(sha1.New, secretb)
- p := New(CryptoHashSHA1, 8, DefTimeStep)
+ mac = hmac.New(sha1.New, secretb)
- cases := []struct {
- desc string
- ts int64
- token string
- steps int
- exp bool
- }{{
- desc: "With OTP ~ timestamp",
+ var cases = []testCase{{
+ desc: `With OTP ~ timestamp`,
ts: 2000000000,
- token: "69279037",
+ token: `69279037`,
steps: 2,
exp: true,
}, {
- desc: "With previous OTP timestamp",
+ desc: `With previous OTP timestamp`,
ts: 2000000000 - DefTimeStep,
- token: "40196847",
+ token: `40196847`,
steps: 2,
exp: true,
}, {
- desc: "With timestamp + DefTimeStep",
+ desc: `With timestamp + DefTimeStep`,
ts: 2000000000 + DefTimeStep,
- token: "69279037",
+ token: `69279037`,
steps: 2,
exp: true,
}}
- for _, c := range cases {
- got := p.verifyWithTimestamp(mac, c.token, c.steps, c.ts)
+ var (
+ c testCase
+ got bool
+ )
+
+ for _, c = range cases {
+ got = proto.verifyWithTimestamp(mac, c.token, c.steps, c.ts)
test.Assert(t, c.desc, c.exp, got)
}
}