Documentation
¶
Overview ¶
Package totp provides code generation for TOTP (RFC 6238) and HOTP (RFC 4226)
Index ¶
- Constants
- Variables
- func Bytes(length int) ([]byte, error)
- func BytesFromSample(length int, samples ...string) ([]byte, error)
- func GenerateOTP(secret string) (string, error)
- func OTPHash(s string) (string, error)
- func String(length int, samples ...string) (string, error)
- func StringB64(length int, samples ...string) (string, error)
- type Config
- type ConfigOption
- type DeliveryMethod
- type ErrCode
- type ErrInvalidCode
- type Error
- type Hash
- type Manager
- type Message
- type MessageType
- type OTP
- func (o *OTP) GenerateRecoveryCodes() []string
- func (o *OTP) OTPCode(address string, method DeliveryMethod) (code string, hash string, err error)
- func (o *OTP) TOTPQRString(u *User) (string, error)
- func (o *OTP) TOTPSecret(u *User) (string, error)
- func (o *OTP) ValidateOTP(code string, hash string) error
- func (o *OTP) ValidateTOTP(ctx context.Context, user *User, code string) error
- type Secret
- type TFAOptions
- type TOTPManager
- type Token
- type TokenState
- type User
Constants ¶
const ( // OTPEmail allows a user to complete TFA with an OTP code delivered via email OTPEmail TFAOptions = "otp_email" // OTPPhone allows a user to complete TFA with an OTP code delivered via phone OTPPhone TFAOptions = "otp_phone" // TOTP allows a user to complete TFA with a TOTP device or application TOTP TFAOptions = "totp" // Phone is a delivery method for text messages Phone DeliveryMethod = "phone" // Email is a delivery method for email Email = "email" // OTPAddress is a message containing an OTP code for contact verification OTPAddress MessageType = "otp_address" // OTPResend is a message containing an OTP code OTPResend MessageType = "otp_resend" // OTPLogin is a message containing an OTP code for login OTPLogin MessageType = "otp_login" // OTPSignup is a message containing an OTP code for signup OTPSignup MessageType = "otp_signup" )
Variables ¶
var ( // ErrCannotDecodeOTPHash is an error representing a failure to decode an OTP hash ErrCannotDecodeOTPHash = errors.New("cannot decode otp hash") // ErrInvalidOTPHashFormat is an error representing an invalid OTP hash format ErrInvalidOTPHashFormat = errors.New("invalid otp hash format") // ErrFailedToHashCode is an error representing a failure to hash code ErrFailedToHashCode = errors.New("failed to hash code") // ErrCipherTextTooShort is an error representing a ciphertext that is too short ErrCipherTextTooShort = errors.New("ciphertext too short") // ErrFailedToCreateCipherBlock is an error representing a failure to create a cipher block ErrFailedToCreateCipherBlock = errors.New("failed to create cipher block") // ErrCannotDecodeSecret is an error representing a failure to decode a secret ErrCannotDecodeSecret = errors.New("cannot decode secret") // ErrCannotWriteSecret is an error representing a failure to write a secret ErrCannotWriteSecret = errors.New("cannot write secret") // ErrFailedToDetermineSecretVersion is an error representing a failure to determine secret version ErrFailedToDetermineSecretVersion = errors.New("failed to determine secret version") // ErrFailedToCreateCipherText is an error representing a failure to create cipher text ErrFailedToCreateCipherText = errors.New("failed to create cipher text") // ErrNoSecretKeyForVersion is an error representing no secret key for version ErrNoSecretKeyForVersion = errors.New("no secret key for version") // ErrNoSecretKey is an error representing no secret key ErrNoSecretKey = errors.New("no secret key") // ErrFailedToValidateCode is an error representing a failure to validate code ErrFailedToValidateCode = errors.New("failed to validate code") // ErrCodeIsNoLongerValid is an error representing a code that is no longer valid ErrCodeIsNoLongerValid = errors.New("code is no longer valid") // ErrIncorrectCodeProvided is an error representing an incorrect code provided ErrIncorrectCodeProvided = errors.New("incorrect code provided") // ErrCannotDecryptSecret is an error representing a failure to decrypt secret ErrCannotDecryptSecret = errors.New("cannot decrypt secret") // ErrFailedToGetSecretForQR is an error representing a failure to get secret for qr ErrFailedToGetSecretForQR = errors.New("failed to get secret for qr") // ErrFailedToGenerateSecret is an error representing a failure to generate secret ErrFailedToGenerateSecret = errors.New("failed to generate secret") // ErrCannotHashOTPString is an error representing a failure to hash otp string ErrCannotHashOTPString = errors.New("cannot hash otp string") // ErrCannotGenerateRandomString is an error representing a failure to generate random string ErrCannotGenerateRandomString = errors.New("cannot generate random string") )
Functions ¶
func BytesFromSample ¶
BytesFromSample returns securely generated random bytes from a string sample
func GenerateOTP ¶
GenerateOTP generates a Time-Based One-Time Password (TOTP).
Types ¶
type Config ¶
type Config struct {
// Enabled is a flag to enable or disable the OTP service
Enabled bool `json:"enabled" koanf:"enabled" default:"true"`
// CodeLength is the length of the OTP code
CodeLength int `json:"codeLength" koanf:"codeLength" default:"6"`
// Issuer is the issuer for TOTP codes
Issuer string `json:"issuer" koanf:"issuer" default:"datum"`
// WithRedis configures the service with a redis client
WithRedis bool `json:"redis" koanf:"redis" default:"true"`
// Secret stores a versioned secret key for cryptography functions
Secret string `json:"secret" koanf:"secret"`
// RecoveryCodeCount is the number of recovery codes to generate
RecoveryCodeCount int `json:"recoveryCodeCount" koanf:"recoveryCodeCount" default:"16"`
// RecoveryCodeLength is the length of a recovery code
RecoveryCodeLength int `json:"recoveryCodeLength" koanf:"recoveryCodeLength" default:"8"`
}
type ConfigOption ¶
type ConfigOption func(*OTP)
ConfigOption configures the validator
func WithCodeLength ¶
func WithCodeLength(length int) ConfigOption
WithCodeLength configures the service with a length for random code generation
func WithIssuer ¶
func WithIssuer(issuer string) ConfigOption
WithIssuer configures the service with a TOTP issuing domain
func WithRecoveryCodeCount ¶
func WithRecoveryCodeCount(count int) ConfigOption
WithRecoveryCodeCount configures the service with a number of recovery codes to generate
func WithRecoveryCodeLength ¶
func WithRecoveryCodeLength(length int) ConfigOption
WithRecoveryCodeLength configures the service with the length of recovery codes to generate
func WithRedis ¶
func WithRedis(db otpRedis) ConfigOption
WithRedis configures the service with a redis client
func WithSecret ¶
func WithSecret(x Secret) ConfigOption
WithSecret sets a new versioned Secret on the client
type DeliveryMethod ¶
type DeliveryMethod string
DeliveryMethod represents a mechanism to send messages to users
type ErrCode ¶
type ErrCode string
ErrCode is a machine readable code representing an error within the authenticator domain
type ErrInvalidCode ¶
type ErrInvalidCode string
ErrInvalidCode represents an error related to an invalid TOTP/OTP code
func (ErrInvalidCode) Code ¶
func (e ErrInvalidCode) Code() ErrCode
func (ErrInvalidCode) Error ¶
func (e ErrInvalidCode) Error() string
func (ErrInvalidCode) Message ¶
func (e ErrInvalidCode) Message() string
type Hash ¶
type Hash struct {
CodeHash string `json:"code_hash"`
ExpiresAt int64 `json:"expires_at"`
Address string `json:"address"`
DeliveryMethod DeliveryMethod `json:"delivery_method"`
}
Hash contains a hash of a OTP code
func FromOTPHash ¶
FromOTPHash parses an OTP hash string to individual parts
type Manager ¶
type Manager struct {
TOTPManager TOTPManager
}
Manager manages the protocol for SMS/Email 2FA codes and TOTP codes
type Message ¶
type Message struct {
// Type describes the classification of a Message
Type MessageType
// Subject is a human readable subject describe the Message
Subject string
// Delivery type of the message (e.g. phone or email)
Delivery DeliveryMethod
// Vars contains key/value variables to populate
// templated content
Vars map[string]string
// Content of the message
Content string
// Delivery address of the user (e.g. phone or email)
Address string
// ExpiresAt is the latest time we can attempt delivery
ExpiresAt time.Time
// DeliveryAttempts is the total amount of delivery attempts made
DeliveryAttempts int
}
Message is a message to be delivered to a user
type OTP ¶
type OTP struct {
// contains filtered or unexported fields
}
OTP is a credential validator for User OTP codes
func (*OTP) GenerateRecoveryCodes ¶
GenerateRecoveryCodes generates a list of recovery codes
func (*OTP) TOTPQRString ¶
TOTPQRString returns a string containing account details for TOTP code generation
func (*OTP) TOTPSecret ¶
TOTPSecret assigns a TOTP secret for a user for use in code generation. TOTP secrets are encrypted by a pre-configured secret key and decrypted only during validation. Encrypted keys are versioned to assist with migrations and backwards compatibility in the event an older secret ever needs to be deprecated.
func (*OTP) ValidateOTP ¶
ValidateOTP checks if a User's OTP code is valid users can input secrets sent by SMS or email (needs to be implemented separately)
func (*OTP) ValidateTOTP ¶
ValidateTOTP checks if a User's TOTP is valid - first validate the TOTP against the user's secret key and then check if the code has been set in redis, indicating that it has been used in the past thirty seconds codes that have been validated are cached to prevent immediate reuse
type TFAOptions ¶
type TFAOptions string
TFAOptions represents options a user may use to complete 2FA
type TOTPManager ¶
type TOTPManager interface {
// TOTPQRString returns a URL string used for TOTP code generation
TOTPQRString(u *User) (string, error)
// TOTPSecret creates a TOTP secret for code generation
TOTPSecret(u *User) (string, error)
// OTPCode creates a random OTP code and hash
OTPCode(address string, method DeliveryMethod) (code, hash string, err error)
// ValidateOTP checks if a User email/sms delivered OTP code is valid
ValidateOTP(code, hash string) error
// ValidateTOTP checks if a User TOTP code is valid
ValidateTOTP(ctx context.Context, user *User, code string) error
// GenerateRecoveryCodes creates a set of recovery codes for a user
GenerateRecoveryCodes() []string
}
TOTPManager manages the protocol for SMS/Email 2FA codes and TOTP codes
type Token ¶
type Token struct {
// Phone is a User's phone number
Phone string `json:"phone_number"`
// CodeHash is the hash of a randomly generated code used
// to validate an OTP code and escalate the token to an
// authorized token
CodeHash string `json:"code,omitempty"`
// Code is the unhashed value of CodeHash. This value is
// not persisted and returned to the client outside of the JWT
// response through an alternative mechanism (e.g. Email). It is
// validated by ensuring the SHA512 hash of the value matches the
// CodeHash embedded in the token
Code string `json:"-"`
// TFAOptions represents available options a user may use to complete
// 2FA.
TFAOptions []TFAOptions `json:"tfa_options"`
}
Token is a token that provides proof of User authentication
type TokenState ¶
type TokenState string
TokenState represents a state of a JWT token. A token may represent an intermediary state prior to authorization (ex. TOTP code is required)
type User ¶
type User struct {
// ID is a unique ID for the user
ID string
// Phone number associated with the account
Phone sql.NullString
// Email address associated with the account
Email sql.NullString
// TFASecret is a a secret string used to generate 2FA TOTP codes
TFASecret string
// IsPhoneAllowed specifies a user may complete authentication by verifying an OTP code delivered through SMS
IsPhoneOTPAllowed bool
// IsEmailOTPAllowed specifies a user may complete authentication by verifying an OTP code delivered through email
IsEmailOTPAllowed bool
// IsTOTPAllowed specifies a user may complete authentication by verifying a TOTP code
IsTOTPAllowed bool
}
User represents a user who is registered with the service
func (*User) DefaultName ¶
DefaultName returns the default name for a user (email or phone)
func (*User) DefaultOTPDelivery ¶
func (u *User) DefaultOTPDelivery() DeliveryMethod
DefaultOTPDelivery returns the default OTP delivery method