Constant-time comparison for cleartext passwords.

Thanks to Stefan Vinck of Radically Open Security.
This commit is contained in:
Juliusz Chroboczek committed 2025-01-17 11:09:59 +01:00
1 parent c465157eb5
commit 3e60248e54
1 file changed
+11 -1
+11 -1
View File
@@ -3,6 +3,7 @@ package group
import ( import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"crypto/subtle"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
@@ -25,6 +26,15 @@ type RawPassword struct {
type Password RawPassword type Password RawPassword
// constantTimeCompare compares a and b in time proportional to the length of a.
func constantTimeCompare(a, b string) bool {
as := []byte(a)
bs := make([]byte, len(as))
copy(bs, a)
equal := subtle.ConstantTimeCompare(as, bs) == 1
return len(a) == len(b) && equal
}
func (p Password) Match(pw string) (bool, error) { func (p Password) Match(pw string) (bool, error) {
switch p.Type { switch p.Type {
case "": case "":
@@ -33,7 +43,7 @@ func (p Password) Match(pw string) (bool, error) {
if p.Key == nil { if p.Key == nil {
return false, errors.New("missing key") return false, errors.New("missing key")
} }
return *p.Key == pw, nil return constantTimeCompare(pw, *p.Key), nil
case "wildcard": case "wildcard":
return true, nil return true, nil
case "pbkdf2": case "pbkdf2":