[MISC] Introduce CryptAlgo type. (#960)
* [MISC] Introduce CryptAlgo type. It helps distinguish between the configuration representation of an algorithm and the crypt representation (6 and argon2id vs sha512 vs argon2id). * Add a description to CryptAlgo. * use const Co-authored-by: James Elliott <james-d-elliott@users.noreply.github.com>pull/967/head
parent
da5c722cf8
commit
e5ccdb4449
|
@ -24,11 +24,14 @@ const (
|
|||
// PossibleMethods is the set of all possible 2FA methods.
|
||||
var PossibleMethods = []string{TOTP, U2F, Push}
|
||||
|
||||
// CryptAlgo the crypt representation of an algorithm used in the prefix of the hash.
|
||||
type CryptAlgo string
|
||||
|
||||
const (
|
||||
// HashingAlgorithmArgon2id Argon2id hash identifier.
|
||||
HashingAlgorithmArgon2id = "argon2id"
|
||||
HashingAlgorithmArgon2id CryptAlgo = "argon2id"
|
||||
// HashingAlgorithmSHA512 SHA512 hash identifier.
|
||||
HashingAlgorithmSHA512 = "6"
|
||||
HashingAlgorithmSHA512 CryptAlgo = "6"
|
||||
)
|
||||
|
||||
// These are the default values from the upstream crypt module we use them to for GetInt
|
||||
|
|
|
@ -51,14 +51,14 @@ func NewFileUserProvider(configuration *schema.FileAuthenticationBackendConfigur
|
|||
panic(err.Error())
|
||||
}
|
||||
|
||||
var cryptAlgo CryptAlgo = HashingAlgorithmArgon2id
|
||||
// TODO: Remove this. This is only here to temporarily fix the username enumeration security flaw in #949.
|
||||
// This generates a hash that should be usable to do a fake CheckUserPassword
|
||||
algorithm := configuration.Password.Algorithm
|
||||
if configuration.Password.Algorithm == sha512 {
|
||||
algorithm = HashingAlgorithmSHA512
|
||||
cryptAlgo = HashingAlgorithmSHA512
|
||||
}
|
||||
settings := getCryptSettings(utils.RandomString(configuration.Password.SaltLength, HashingPossibleSaltCharacters),
|
||||
algorithm, configuration.Password.Iterations, configuration.Password.Memory*1024, configuration.Password.Parallelism,
|
||||
cryptAlgo, configuration.Password.Iterations, configuration.Password.Memory*1024, configuration.Password.Parallelism,
|
||||
configuration.Password.KeyLength)
|
||||
data := crypt.Base64Encoding.EncodeToString([]byte(utils.RandomString(configuration.Password.KeyLength, HashingPossibleSaltCharacters)))
|
||||
fakeHash := fmt.Sprintf("%s$%s", settings, data)
|
||||
|
@ -140,7 +140,7 @@ func (p *FileUserProvider) UpdatePassword(username string, newPassword string) e
|
|||
return fmt.Errorf("User '%s' does not exist in database", username)
|
||||
}
|
||||
|
||||
var algorithm string
|
||||
var algorithm CryptAlgo
|
||||
if p.configuration.Password.Algorithm == "argon2id" {
|
||||
algorithm = HashingAlgorithmArgon2id
|
||||
} else if p.configuration.Password.Algorithm == sha512 {
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
// PasswordHash represents all characteristics of a password hash.
|
||||
// Authelia only supports salted SHA512 or salted argon2id method, i.e., $6$ mode or $argon2id$ mode.
|
||||
type PasswordHash struct {
|
||||
Algorithm string
|
||||
Algorithm CryptAlgo
|
||||
Iterations int
|
||||
Salt string
|
||||
Key string
|
||||
|
@ -28,7 +28,8 @@ func ParseHash(hash string) (passwordHash *PasswordHash, err error) {
|
|||
parts := strings.Split(hash, "$")
|
||||
|
||||
// This error can be ignored as it's always nil.
|
||||
code, parameters, salt, key, _ := crypt.DecodeSettings(hash)
|
||||
c, parameters, salt, key, _ := crypt.DecodeSettings(hash)
|
||||
code := CryptAlgo(c)
|
||||
h := &PasswordHash{}
|
||||
|
||||
h.Salt = salt
|
||||
|
@ -83,7 +84,7 @@ func ParseHash(hash string) (passwordHash *PasswordHash, err error) {
|
|||
|
||||
// HashPassword generate a salt and hash the password with the salt and a constant number of rounds.
|
||||
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
|
||||
func HashPassword(password, salt, algorithm string, iterations, memory, parallelism, keyLength, saltLength int) (hash string, err error) {
|
||||
func HashPassword(password, salt string, algorithm CryptAlgo, iterations, memory, parallelism, keyLength, saltLength int) (hash string, err error) {
|
||||
var settings string
|
||||
|
||||
if algorithm != HashingAlgorithmArgon2id && algorithm != HashingAlgorithmSHA512 {
|
||||
|
@ -147,7 +148,7 @@ func CheckPassword(password, hash string) (ok bool, err error) {
|
|||
return hash == expectedHash, nil
|
||||
}
|
||||
|
||||
func getCryptSettings(salt, algorithm string, iterations, memory, parallelism, keyLength int) (settings string) {
|
||||
func getCryptSettings(salt string, algorithm CryptAlgo, iterations, memory, parallelism, keyLength int) (settings string) {
|
||||
if algorithm == HashingAlgorithmArgon2id {
|
||||
settings, _ = crypt.Argon2idSettings(memory, iterations, parallelism, keyLength, salt)
|
||||
} else if algorithm == HashingAlgorithmSHA512 {
|
||||
|
|
|
@ -34,7 +34,7 @@ var HashPasswordCmd = &cobra.Command{
|
|||
|
||||
var err error
|
||||
var hash string
|
||||
var algorithm string
|
||||
var algorithm authentication.CryptAlgo
|
||||
|
||||
if sha512 {
|
||||
if iterations == schema.DefaultPasswordConfiguration.Iterations {
|
||||
|
|
Loading…
Reference in New Issue