[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>
This commit is contained in:
Clément Michaud 2020-05-03 06:06:09 +02:00 committed by GitHub
parent da5c722cf8
commit e5ccdb4449
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 11 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {