diff options
| author | Shulhan <ms@kilabit.info> | 2022-08-06 23:07:28 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2022-08-06 23:07:33 +0700 |
| commit | 0bb0c3cc265565a7abd2d2cd84e7f3865f5777f3 (patch) | |
| tree | 300d76e662149fac17f4cdfa2bab7862c378b475 | |
| parent | 055802ca21d6c1e8c8427bd9553a821fbb7ef721 (diff) | |
| download | pakakeh.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.go | 90 | ||||
| -rw-r--r-- | lib/totp/totp_example_test.go | 25 | ||||
| -rw-r--r-- | lib/totp/totp_test.go | 199 |
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) } } |
