Documentation
¶
Overview ¶
Package totp implements RFC 6238 TOTP (time-based one-time password) enrollment and verification. We use SHA-1 / 30-second period / 6 digits to maximize authenticator-app compatibility (every popular app speaks these defaults; SHA-256/512 cause real-world surprises).
Counter anti-replay is enforced at the DB layer (BumpTOTPCounter only advances last_used_counter when the new step is strictly greater).
Index ¶
- Constants
- Variables
- func EncodeBase32(secret []byte) string
- func EqualHash(a, b []byte) bool
- func Generate(secret []byte, t time.Time) (string, error)
- func GenerateRecoveryCodes() ([]string, [][]byte, error)
- func GenerateSecret() ([]byte, error)
- func HashRecoveryCode(code string) []byte
- func LooksLikeRecoveryCode(s string) bool
- func NormalizeRecoveryCode(s string) string
- func OtpauthURI(issuer, accountName string, secret []byte) string
- func QRSVG(otpauthURI string) (template.HTML, error)
- func Step(t time.Time) int64
- func Verify(secret []byte, code string, t time.Time) (int64, error)
Constants ¶
const Digits = otp.DigitsSix
Digits is the number of digits in the generated code.
const Period uint = 30
Period is the time-step in seconds.
const QRSize = 256
QRSize is the rendered SVG side length in CSS pixels (the SVG itself is resolution-independent; this drives the viewport-mapped size).
const RecoveryCodeCount = 10
RecoveryCodeCount is the number of recovery codes generated per user.
const RecoveryCodeGroupSize = 4
RecoveryCodeGroupSize is the length of each group.
const RecoveryCodeGroups = 3
RecoveryCodeGroups is the number of dash-separated groups in the rendered code (currently 3, of 4 chars each → 12 chars total).
const SecretSize = 20
SecretSize is the secret length in bytes. 20 is the RFC 4226/6238 recommendation (160 bits — comfortably above brute-force reach).
const SkewSteps uint = 1
SkewSteps is the number of windows ±0 we accept either side of `now`. A value of 1 means accept now-30s, now, now+30s — covers normal clock drift without expanding the replay window meaningfully.
Variables ¶
var ErrInvalid = errors.New("totp: invalid code")
ErrInvalid means the code doesn't match (or doesn't look like one). Distinct from a generation error so callers can branch on it.
var ErrRecoveryCodeInvalid = errors.New("totp: recovery code invalid")
ErrRecoveryCodeInvalid is returned by callers when the typed code doesn't match any stored hash.
Functions ¶
func EncodeBase32 ¶
EncodeBase32 returns the Base32 encoding (no padding) authenticator apps display to the user. Used in the otpauth URI.
func EqualHash ¶
EqualHash compares two recovery-code hashes in constant time. Used by callers that read a candidate hash from the DB and want to compare to a value they computed themselves.
func Generate ¶
Generate returns the current 6-digit code for secret. Test affordance — not used at runtime by the server, only in tests.
func GenerateRecoveryCodes ¶
GenerateRecoveryCodes mints RecoveryCodeCount fresh codes. Returns the human-readable strings (XXXX-XXXX-XXXX) that are shown to the user once, and the matching sha256 hashes (stored in the DB).
func GenerateSecret ¶
GenerateSecret returns a fresh 20-byte secret.
func HashRecoveryCode ¶
HashRecoveryCode returns the sha256 hash of the normalized form of code, suitable for DB lookup.
func LooksLikeRecoveryCode ¶
LooksLikeRecoveryCode is a cheap predicate the login challenge handler uses to distinguish a recovery code from a TOTP code: alphanumeric and of the expected post-normalization length.
func NormalizeRecoveryCode ¶
NormalizeRecoveryCode strips dashes/whitespace and uppercases the result so codes typed with stray spaces or lowercase still match.
func OtpauthURI ¶
OtpauthURI builds the canonical otpauth:// URI consumed by authenticator apps. issuer is the site name (e.g. "shithub"); accountName is the user's canonical identifier (we use "shithub:<username>"). The URI carries the secret in plaintext — never log it; redactor scrubs it as defense in depth.
func QRSVG ¶
QRSVG renders the otpauth URI as an SVG QR code suitable for inline embedding in a template. Returns template.HTML so html/template doesn't double-escape the markup.
The URI is high-entropy and contains the secret. Callers MUST NOT log either the URI or the rendered SVG.
func Verify ¶
Verify checks code against secret with ±SkewSteps tolerance. On acceptance, returns the step counter that matched so the caller can reject codes whose counter is <= last_used_counter.
Returns (step, nil) on accepted code; (0, err) otherwise. err is distinguishable via ErrInvalid for bad codes (vs. real errors).
Types ¶
This section is empty.