Skip to content

Commit 08498e3

Browse files
authored
Merge pull request #19 from thevilledev/fix/rng-fullread
fix: use io.ReadFull for salt generation
2 parents 4398de0 + 74e08a8 commit 08498e3

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func (c Config) NewCredential(userID UserID, password string) (*Credential, erro
135135
return nil, passwordPolicyFailures
136136
}
137137
salt := make([]byte, c.SaltSize)
138-
if _, err := randReader.Read(salt); err != nil {
138+
if _, err := io.ReadFull(randReader, salt); err != nil {
139139
return nil, err
140140
}
141141
hash, err := getPasswordHash(c.Kdf, c.WorkFactor, salt, c.KeyLength, password)

config_test.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package passhash_test
22

33
import (
44
"errors"
5+
"io"
56
"testing"
6-
)
77

8-
import (
98
"github.com/dhui/passhash"
109
)
1110

@@ -172,3 +171,37 @@ func TestScryptWorkFactorUnmarshalError(t *testing.T) {
172171
testWorkFactorUnmarshalError(t, []int{1, 2}, &passhash.BcryptWorkFactor{})
173172
testWorkFactorUnmarshalError(t, []int{1, 2, 3, 4}, &passhash.BcryptWorkFactor{})
174173
}
174+
175+
// eofAfterNReader returns at most n bytes, then EOF.
176+
// This simulates a short-reading RNG that terminates early.
177+
type eofAfterNReader struct {
178+
remaining int
179+
}
180+
181+
func (r *eofAfterNReader) Read(p []byte) (int, error) {
182+
if r.remaining <= 0 {
183+
return 0, io.EOF
184+
}
185+
n := r.remaining
186+
if n > len(p) {
187+
n = len(p)
188+
}
189+
for i := 0; i < n; i++ {
190+
p[i] = byte(i + 1)
191+
}
192+
r.remaining -= n
193+
return n, nil
194+
}
195+
196+
func TestNewCredentialWithShortEOFReader(t *testing.T) {
197+
prev := passhash.GetRandReader()
198+
t.Cleanup(func() { passhash.SetRandReader(prev) })
199+
200+
cfg := passhash.DefaultConfig
201+
cfg.SaltSize = 16
202+
203+
passhash.SetRandReader(&eofAfterNReader{remaining: 4})
204+
if _, err := cfg.NewCredential(42, "password-1234567890"); err == nil {
205+
t.Fatalf("expected error due to short-reading RNG with EOF, got nil")
206+
}
207+
}

0 commit comments

Comments
 (0)