Skip to content

Commit

Permalink
Merge f5551ff into 3cf7ac4
Browse files Browse the repository at this point in the history
  • Loading branch information
NSEcho committed Oct 2, 2019
2 parents 3cf7ac4 + f5551ff commit 4a372ce
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -94,6 +94,10 @@ func main() {
// DictionaryPath contains all the dictionaries that will be parsed
// (default is /usr/share/dict)
DictionaryPath: "/var/my/own/dicts",

// Check haveibeenpwned.com database
// Default is false
CheckHIBP: true,
})
...
}
Expand Down
9 changes: 9 additions & 0 deletions crunchy.go
Expand Up @@ -40,13 +40,16 @@ type Options struct {
Hashers []hash.Hash
// DictionaryPath contains all the dictionaries that will be parsed (default is /usr/share/dict)
DictionaryPath string
// Check haveibeenpwned.com database
CheckHIBP bool
}

// NewValidator returns a new password validator with default settings
func NewValidator() *Validator {
return NewValidatorWithOpts(Options{
MinDist: -1,
DictionaryPath: "/usr/share/dict",
CheckHIBP: false,
})
}

Expand Down Expand Up @@ -158,6 +161,12 @@ func (v *Validator) Check(password string) error {
if countUniqueChars(password) < v.options.MinDiff {
return ErrTooFewChars
}
if v.options.CheckHIBP {
err := foundInHIBP(password)
if err != nil {
return err
}
}

// Inspired by cracklib
maxrepeat := 3.0 + (0.09 * float64(len(password)))
Expand Down
10 changes: 10 additions & 0 deletions crunchy_test.go
Expand Up @@ -43,6 +43,7 @@ var (
{"87654321", ErrTooSystematic, 0},
{"abcdefgh", ErrTooSystematic, 0},
{"hgfedcba", ErrTooSystematic, 0},
{"Qwertyuiop", ErrFoundHIBP, 0},

{"password", ErrDictionary, 0},
{"intoxicate", ErrDictionary, 0},
Expand Down Expand Up @@ -70,6 +71,15 @@ func TestValidatePassword(t *testing.T) {
})

for _, pw := range pws {
if pw.expected == ErrFoundHIBP {
v.options.CheckHIBP = true
er := v.Check(pw.pw)
if er != pw.expected {
t.Errorf("Expected %v for password '%s', got %v", pw.expected, pw.pw, er)
}
v.options.CheckHIBP = false
continue
}
r, err := v.Rate(pw.pw)
if dicterr, ok := err.(*DictionaryError); ok {
err = dicterr.Err
Expand Down
2 changes: 2 additions & 0 deletions errors.go
Expand Up @@ -47,4 +47,6 @@ var (
ErrMangledDictionary = errors.New("Password is mangled, but too common / from a dictionary")
// ErrHashedDictionary gets returned when the password is hashed, but found in a dictionary
ErrHashedDictionary = errors.New("Password is hashed, but too common / from a dictionary")
// ErrFoundInPwned gets returned when the password has been found on https://haveibeenpwned.com
ErrFoundHIBP = errors.New("Password has been found inside haveibeenpwned.com database")
)
39 changes: 39 additions & 0 deletions hibp.go
@@ -0,0 +1,39 @@
package crunchy

import (
"crypto/sha1"
"encoding/hex"
"io/ioutil"
"net/http"
"strings"
)

func foundInHIBP(s string) error {
h := sha1.New()
h.Write([]byte(s))
result := hex.EncodeToString(h.Sum(nil))

firstFive := result[0:5]
restOfHash := strings.ToUpper(result[5:])

url := "https://api.pwnedpasswords.com/range/" + firstFive

resp, err := http.Get(url)
if err != nil {
return err
}

defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}

if strings.Index(string(body), restOfHash) > -1 {
return ErrFoundHIBP
}

return nil

}

0 comments on commit 4a372ce

Please sign in to comment.