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