Restart.
Data foundation started, with updated guidelines and golangci-lint config.
This commit is contained in:
47
data/totp.go
Normal file
47
data/totp.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
twofactor "git.wntrmute.dev/kyle/goutils/twofactor"
|
||||
)
|
||||
|
||||
const totpPeriod = 30
|
||||
|
||||
// builtinTOTPValidator delegates TOTP validation to goutils/twofactor.
|
||||
type builtinTOTPValidator struct{}
|
||||
|
||||
func (builtinTOTPValidator) Validate(secret, code string, at time.Time, window int) bool {
|
||||
if secret == "" || code == "" {
|
||||
return false
|
||||
}
|
||||
// Normalize secret similar to common authenticator apps: remove spaces and uppercase.
|
||||
norm := strings.ToUpper(strings.ReplaceAll(secret, " ", ""))
|
||||
norm = twofactor.Pad(norm)
|
||||
otp, err := twofactor.NewGoogleTOTP(norm)
|
||||
if err != nil || otp == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Compute the base counter for the provided time (period 30s, start 0).
|
||||
base := uint64(at.Unix()&unsignedMask64) / totpPeriod // #nosec G115 - masked off overflow
|
||||
// Check +/- window steps.
|
||||
for i := -window; i <= window; i++ {
|
||||
var ctr uint64
|
||||
if i < 0 {
|
||||
// Guard underflow.
|
||||
offs := uint64(-i)
|
||||
if offs > base {
|
||||
continue
|
||||
}
|
||||
ctr = base - offs
|
||||
} else {
|
||||
ctr = base + uint64(i)
|
||||
}
|
||||
if otp.OATH.OTP(ctr) == code {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user