Skip to content

Commit

Permalink
Add error handling for base64 DecodeString operations
Browse files Browse the repository at this point in the history
Modify pw to use 0 for default key length, which will then cause algorithum default hash size to be used, vs hard-coded default of '32'

Make salt_encoding option plugin specific by adding plugin prefix
  • Loading branch information
coldfire84 committed Jan 18, 2020
1 parent 07e5cab commit dd60047
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 11 deletions.
2 changes: 1 addition & 1 deletion backends/mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func NewMongo(authOpts map[string]string, logLevel log.Level) (Mongo, error) {
m.Password = mongoPassword
}

if saltEncoding, ok := authOpts["salt_encoding"]; ok {
if saltEncoding, ok := authOpts["mongo_salt_encoding"]; ok {
m.SaltEncoding = saltEncoding
log.Infof("Mongo set salt encoding to: %s", saltEncoding)
} else {
Expand Down
2 changes: 1 addition & 1 deletion backends/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func NewMysql(authOpts map[string]string, logLevel log.Level) (Mysql, error) {
missingOptions += " mysql_password"
}

if saltEncoding, ok := authOpts["salt_encoding"]; ok {
if saltEncoding, ok := authOpts["mysql_salt_encoding"]; ok {
mysql.SaltEncoding = saltEncoding
} else {
mysql.SaltEncoding = "base64"
Expand Down
2 changes: 1 addition & 1 deletion backends/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func NewPostgres(authOpts map[string]string, logLevel log.Level) (Postgres, erro
missingOptions += " pg_password"
}

if saltEncoding, ok := authOpts["salt_encoding"]; ok {
if saltEncoding, ok := authOpts["pg_salt_encoding"]; ok {
postgres.SaltEncoding = saltEncoding
} else {
postgres.SaltEncoding = "base64"
Expand Down
2 changes: 1 addition & 1 deletion backends/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func NewRedis(authOpts map[string]string, logLevel log.Level) (Redis, error) {
redis.Password = redisPassword
}

if saltEncoding, ok := authOpts["salt_encoding"]; ok {
if saltEncoding, ok := authOpts["redis_salt_encoding"]; ok {
redis.SaltEncoding = saltEncoding
} else {
redis.SaltEncoding = "base64"
Expand Down
2 changes: 1 addition & 1 deletion backends/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func NewSqlite(authOpts map[string]string, logLevel log.Level) (Sqlite, error) {
sqlite.AclQuery = aclQuery
}

if saltEncoding, ok := authOpts["salt_encoding"]; ok {
if saltEncoding, ok := authOpts["sqlite_salt_encoding"]; ok {
sqlite.SaltEncoding = saltEncoding
} else {
sqlite.SaltEncoding = "base64"
Expand Down
17 changes: 13 additions & 4 deletions common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,28 +122,37 @@ func hashWithSalt(password string, salt []byte, iterations int, algorithm string
}
buffer.WriteString("$")
buffer.WriteString(base64.StdEncoding.EncodeToString(hash))
//log.Println("Generated: ", buffer.String())
//log.Debugf("Generated: ", buffer.String())
return buffer.String()
}

// HashCompare verifies that passed password hashes to the same value as the
// passed passwordHash.
// Taken from brocaar's lora-app-server: https://github.com/brocaar/lora-app-server
func HashCompare(password string, passwordHash string, saltEncoding string) bool {
//log.Println("Supplied: ", passwordHash)
//log.Debugf("Supplied: ", passwordHash)
// Split the hash string into its parts.
hashSplit := strings.Split(passwordHash, "$")
// Get the iterations from PBKDF2 string
iterations, _ := strconv.Atoi(hashSplit[2])
// Convert salt to bytes, using encoding supplied in saltEncoding param
salt := []byte{}
var err error
if saltEncoding == "utf-8" {
salt = []byte(hashSplit[3])
} else {
salt, _ = base64.StdEncoding.DecodeString(hashSplit[3])
salt, err = base64.StdEncoding.DecodeString(hashSplit[3])
if err != nil {
log.Errorf("Error decoding supplied base64 salt")
return false
}
}
// Work out key length, assumes base64 encoding
hash, _ := base64.StdEncoding.DecodeString(hashSplit[4])
hash, err := base64.StdEncoding.DecodeString(hashSplit[4])
if err != nil {
log.Errorf("Error decoding supplied base64 hash")
return false
}
keylen := len(hash)
// Get the algorithm from PBKDF2 string
algorithm := hashSplit[1]
Expand Down
21 changes: 19 additions & 2 deletions pw-gen/pw.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,33 @@ import (

func main() {

const(
sha256Size = 32
sha512Size = 64
)

var algorithm = flag.String("a", "sha512", "algorithm: sha256 or sha512")
var HashIterations = flag.Int("i", 100000, "hash iterations")
var password = flag.String("p", "", "password")
var saltSize = flag.Int("s", 16, "salt size")
var saltEncoding = flag.String("e", "base64", "salt encoding")
var keylen = flag.Int("l", 64, "key length, reccommend 32 for sha256 and 64 for sha512")
var keylen = flag.Int("l", 0, "key length, recommend 32 for sha256 and 64 for sha512")

flag.Parse()

pwHash, err := common.Hash(*password, *saltSize, *HashIterations, *algorithm, *saltEncoding, *keylen)
// If supplied keylength is 0, use pre-defined key length
shaSize := *keylen
if shaSize == 0 {
switch *algorithm {
case "sha265": shaSize = sha256Size
case "sha512": shaSize = sha512Size
default:
fmt.Printf("Invalid password hash algorithm", *algorithm)
return
}
}

pwHash, err := common.Hash(*password, *saltSize, *HashIterations, *algorithm, *saltEncoding, shaSize)
if err != nil {
fmt.Printf("error: %s\n", err)
} else {
Expand Down

0 comments on commit dd60047

Please sign in to comment.