2020-02-01 12:54:50 +00:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
import (
|
2021-11-23 09:45:38 +00:00
|
|
|
"errors"
|
2020-04-05 12:37:21 +00:00
|
|
|
"time"
|
|
|
|
|
2020-03-25 01:48:20 +00:00
|
|
|
"github.com/pquerna/otp"
|
2020-02-01 12:54:50 +00:00
|
|
|
"github.com/pquerna/otp/totp"
|
2021-11-23 09:45:38 +00:00
|
|
|
|
|
|
|
"github.com/authelia/authelia/v4/internal/models"
|
2020-02-01 12:54:50 +00:00
|
|
|
)
|
|
|
|
|
2020-04-20 21:03:38 +00:00
|
|
|
// TOTPVerifier is the interface for verifying TOTPs.
|
2020-02-01 12:54:50 +00:00
|
|
|
type TOTPVerifier interface {
|
2021-11-23 09:45:38 +00:00
|
|
|
Verify(config *models.TOTPConfiguration, token string) (bool, error)
|
2020-02-01 12:54:50 +00:00
|
|
|
}
|
|
|
|
|
2020-04-20 21:03:38 +00:00
|
|
|
// TOTPVerifierImpl the production implementation for TOTP verification.
|
2020-03-25 01:48:20 +00:00
|
|
|
type TOTPVerifierImpl struct {
|
|
|
|
Period uint
|
|
|
|
Skew uint
|
|
|
|
}
|
2020-02-01 12:54:50 +00:00
|
|
|
|
2020-04-20 21:03:38 +00:00
|
|
|
// Verify verifies TOTPs.
|
2021-11-23 09:45:38 +00:00
|
|
|
func (tv *TOTPVerifierImpl) Verify(config *models.TOTPConfiguration, token string) (bool, error) {
|
|
|
|
if config == nil {
|
|
|
|
return false, errors.New("config not provided")
|
|
|
|
}
|
|
|
|
|
2020-03-25 01:48:20 +00:00
|
|
|
opts := totp.ValidateOpts{
|
2021-11-23 09:45:38 +00:00
|
|
|
Period: uint(config.Period),
|
2020-03-25 01:48:20 +00:00
|
|
|
Skew: tv.Skew,
|
2021-11-23 09:45:38 +00:00
|
|
|
Digits: otp.Digits(config.Digits),
|
|
|
|
Algorithm: otpStringToAlgo(config.Algorithm),
|
2020-03-25 01:48:20 +00:00
|
|
|
}
|
2020-05-05 19:35:32 +00:00
|
|
|
|
2021-11-23 09:45:38 +00:00
|
|
|
return totp.ValidateCustom(token, config.Secret, time.Now().UTC(), opts)
|
|
|
|
}
|
|
|
|
|
|
|
|
func otpAlgoToString(algorithm otp.Algorithm) (out string) {
|
|
|
|
switch algorithm {
|
|
|
|
case otp.AlgorithmSHA1:
|
|
|
|
return totpAlgoSHA1
|
|
|
|
case otp.AlgorithmSHA256:
|
|
|
|
return totpAlgoSHA256
|
|
|
|
case otp.AlgorithmSHA512:
|
|
|
|
return totpAlgoSHA512
|
|
|
|
default:
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func otpStringToAlgo(in string) (algorithm otp.Algorithm) {
|
|
|
|
switch in {
|
|
|
|
case totpAlgoSHA1:
|
|
|
|
return otp.AlgorithmSHA1
|
|
|
|
case totpAlgoSHA256:
|
|
|
|
return otp.AlgorithmSHA256
|
|
|
|
case totpAlgoSHA512:
|
|
|
|
return otp.AlgorithmSHA512
|
|
|
|
default:
|
|
|
|
return otp.AlgorithmSHA1
|
|
|
|
}
|
2020-02-01 12:54:50 +00:00
|
|
|
}
|