mirror of
https://github.com/rls-moe/nyx
synced 2024-11-14 22:12:24 +00:00
83 lines
1.6 KiB
Go
83 lines
1.6 KiB
Go
package raw
|
|
|
|
import "fmt"
|
|
import "strings"
|
|
import "strconv"
|
|
|
|
// Indicates that a password hash or stub is invalid.
|
|
var ErrInvalidStub = fmt.Errorf("invalid stub")
|
|
|
|
// Indicates that the number of rounds specified is not in the valid range.
|
|
var ErrInvalidRounds = fmt.Errorf("invalid number of rounds")
|
|
|
|
// Scans a sha256-crypt or sha512-crypt modular crypt stub or modular crypt hash
|
|
// to determine configuration parameters.
|
|
func Parse(stub string) (isSHA512 bool, salt, hash string, rounds int, err error) {
|
|
// $5$
|
|
if len(stub) < 3 || stub[0] != '$' || stub[2] != '$' {
|
|
err = ErrInvalidStub
|
|
return
|
|
}
|
|
|
|
if stub[1] == '6' {
|
|
isSHA512 = true
|
|
} else if stub[1] != '5' {
|
|
err = ErrInvalidStub
|
|
return
|
|
}
|
|
|
|
rest := stub[3:]
|
|
parts := strings.Split(rest, "$")
|
|
roundsStr := ""
|
|
|
|
switch len(parts) {
|
|
case 1:
|
|
// $5$
|
|
// $5$salt
|
|
salt = parts[0]
|
|
case 2:
|
|
// $5$salt$hash
|
|
// $5$rounds=1000$salt
|
|
if strings.HasPrefix(parts[0], "rounds=") {
|
|
roundsStr = parts[0]
|
|
salt = parts[1]
|
|
} else {
|
|
salt = parts[0]
|
|
hash = parts[1]
|
|
}
|
|
case 3:
|
|
// $5$rounds=1000$salt$hash
|
|
roundsStr = parts[0]
|
|
salt = parts[1]
|
|
hash = parts[2]
|
|
default:
|
|
err = ErrInvalidStub
|
|
}
|
|
|
|
if roundsStr != "" {
|
|
if !strings.HasPrefix(roundsStr, "rounds=") {
|
|
err = ErrInvalidStub
|
|
return
|
|
}
|
|
|
|
roundsStr = roundsStr[7:]
|
|
var n uint64
|
|
n, err = strconv.ParseUint(roundsStr, 10, 31)
|
|
if err != nil {
|
|
err = ErrInvalidStub
|
|
return
|
|
}
|
|
|
|
rounds = int(n)
|
|
|
|
if rounds < MinimumRounds || rounds > MaximumRounds {
|
|
err = ErrInvalidRounds
|
|
return
|
|
}
|
|
} else {
|
|
rounds = DefaultRounds
|
|
}
|
|
|
|
return
|
|
}
|