From 663f5f6b7617919acf0662b622c8cf3f4c493951 Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Mon, 20 Sep 2021 10:24:52 +0200 Subject: [PATCH] add totp generator from: https://github.com/yitsushi/totp-cli/blob/master/security/otp.go --- helper/totp.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 helper/totp.go diff --git a/helper/totp.go b/helper/totp.go new file mode 100644 index 0000000..42cf7b9 --- /dev/null +++ b/helper/totp.go @@ -0,0 +1,60 @@ +package helper + +import ( + "crypto/hmac" + "crypto/sha1" + "encoding/base32" + "encoding/binary" + "fmt" + "math" + "strings" + "time" +) + +const ( + mask1 = 0xf + mask2 = 0x7f + mask3 = 0xff + timeSplitInSeconds = 30 + shift24 = 24 + shift16 = 16 + shift8 = 8 + codeLength = 6 +) + +// GenerateOTPCode generates a 6 digit TOTP from the secret Token. +func GenerateOTPCode(token string, when time.Time) (string, error) { + timer := uint64(math.Floor(float64(when.Unix()) / float64(timeSplitInSeconds))) + // Remove spaces, some providers are giving us in a readable format + // so they add spaces in there. If it's not removed while pasting in, + // remove it now. + token = strings.Replace(token, " ", "", -1) + + // It should be uppercase always + token = strings.ToUpper(token) + + secretBytes, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(token) + if err != nil { + return "", fmt.Errorf("Decoding token string: %w", err) + } + + buf := make([]byte, 8) + mac := hmac.New(sha1.New, secretBytes) + + binary.BigEndian.PutUint64(buf, timer) + _, _ = mac.Write(buf) + sum := mac.Sum(nil) + + // http://tools.ietf.org/html/rfc4226#section-5.4 + offset := sum[len(sum)-1] & mask1 + value := int64(((int(sum[offset]) & mask2) << shift24) | + ((int(sum[offset+1] & mask3)) << shift16) | + ((int(sum[offset+2] & mask3)) << shift8) | + (int(sum[offset+3]) & mask3)) + + modulo := int32(value % int64(math.Pow10(codeLength))) + + format := fmt.Sprintf("%%0%dd", codeLength) + + return fmt.Sprintf(format, modulo), nil +}