diff options
author | Quentin Dufour <quentin@deuxfleurs.fr> | 2023-03-26 09:35:28 +0200 |
---|---|---|
committer | Quentin Dufour <quentin@deuxfleurs.fr> | 2023-03-26 09:41:22 +0200 |
commit | a2be316d91e3117d620f39a29b910349f730760d (patch) | |
tree | 2acb0e1a86a5ca509935cce6e86d2c16cefc3b7e | |
parent | 9cab98d2cee386ece54b000bbdf2346da8b55eed (diff) | |
download | bottin-a2be316d91e3117d620f39a29b910349f730760d.tar.gz bottin-a2be316d91e3117d620f39a29b910349f730760d.zip |
use legacy ssha algorithm, new one is incompatible
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | ssha.go | 70 |
2 files changed, 66 insertions, 5 deletions
@@ -3,3 +3,4 @@ bottin.static config.json test/test result +ldap.json @@ -2,8 +2,16 @@ package main import ( "errors" + "strings" - "github.com/jsimonetti/pwscheme/ssha" + "bytes" + "crypto/rand" + "crypto/sha1" + "encoding/base64" + "fmt" + log "github.com/sirupsen/logrus" + + //"github.com/jsimonetti/pwscheme/ssha" "github.com/jsimonetti/pwscheme/ssha256" "github.com/jsimonetti/pwscheme/ssha512" ) @@ -26,9 +34,12 @@ func SSHAMatches(encodedPassPhrase string, rawPassPhrase string) (bool, error) { return false, errors.New("invalid password hash stored") } + var is_ok bool switch hashType { case SSHA: - return ssha.Validate(rawPassPhrase, encodedPassPhrase) + is_ok = LegacySSHAMatches(encodedPassPhrase, []byte(rawPassPhrase)) + return is_ok, nil + //return ssha.Validate(rawPassPhrase, encodedPassPhrase) case SSHA256: return ssha256.Validate(rawPassPhrase, encodedPassPhrase) case SSHA512: @@ -39,15 +50,64 @@ func SSHAMatches(encodedPassPhrase string, rawPassPhrase string) (bool, error) { } func determineHashType(hash string) (string, error) { - if len(hash) >= 7 && string(hash[0:6]) == SSHA { + if len(hash) >= 7 && strings.ToUpper(string(hash[0:6])) == SSHA { return SSHA, nil } - if len(hash) >= 10 && string(hash[0:9]) == SSHA256 { + if len(hash) >= 10 && strings.ToUpper(string(hash[0:9])) == SSHA256 { return SSHA256, nil } - if len(hash) >= 10 && string(hash[0:9]) == SSHA512 { + if len(hash) >= 10 && strings.ToUpper(string(hash[0:9])) == SSHA512 { return SSHA512, nil } return "", errors.New("no valid hash found") } + +// --- legacy + +// Encode encodes the []byte of raw password +func LegacySSHAEncode(rawPassPhrase []byte) string { + hash := legacyMakeSSHAHash(rawPassPhrase, legacyMakeSalt()) + b64 := base64.StdEncoding.EncodeToString(hash) + return fmt.Sprintf("{ssha}%s", b64) +} + +// Matches matches the encoded password and the raw password +func LegacySSHAMatches(encodedPassPhrase string, rawPassPhrase []byte) bool { + if !strings.EqualFold(encodedPassPhrase[:6], "{ssha}") { + return false + } + + bhash, err := base64.StdEncoding.DecodeString(encodedPassPhrase[6:]) + if err != nil { + return false + } + salt := bhash[20:] + + newssha := legacyMakeSSHAHash(rawPassPhrase, salt) + + if bytes.Compare(newssha, bhash) != 0 { + return false + } + return true +} + +// makeSalt make a 32 byte array containing random bytes. +func legacyMakeSalt() []byte { + sbytes := make([]byte, 32) + _, err := rand.Read(sbytes) + if err != nil { + log.Panicf("Could not read random bytes: %s", err) + } + return sbytes +} + +// makeSSHAHash make hasing using SHA-1 with salt. This is not the final output though. You need to append {SSHA} string with base64 of this hash. +func legacyMakeSSHAHash(passphrase, salt []byte) []byte { + sha := sha1.New() + sha.Write(passphrase) + sha.Write(salt) + + h := sha.Sum(nil) + return append(h, salt...) +} |