Skip to content

Commit 6c586e1

Browse files
Andreas Auernhammerbradfitz
Andreas Auernhammer
authored andcommitted
bcrypt: fix C compatibility code
The bcrypt implementation must append a zero byte to the user provided key to be compatible to C implementations. This will change the user provided key if the slice has enough capacity to hold the extra zero byte. This change always allocates a new slice for the C-compatible key. Fixes golang/go#20425 Change-Id: I8dc4e840c29711daabdabe58d83643cc0103cedd Reviewed-on: https://go-review.googlesource.com/43715 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
1 parent 0fe9631 commit 6c586e1

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

bcrypt/bcrypt.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ import (
1212
"crypto/subtle"
1313
"errors"
1414
"fmt"
15-
"golang.org/x/crypto/blowfish"
1615
"io"
1716
"strconv"
17+
18+
"golang.org/x/crypto/blowfish"
1819
)
1920

2021
const (
@@ -205,15 +206,15 @@ func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
205206
}
206207

207208
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
208-
209209
csalt, err := base64Decode(salt)
210210
if err != nil {
211211
return nil, err
212212
}
213213

214214
// Bug compatibility with C bcrypt implementations. They use the trailing
215215
// NULL in the key string during expansion.
216-
ckey := append(key, 0)
216+
// We copy the key to prevent changing the underlying array.
217+
ckey := append(key[:len(key):len(key)], 0)
217218

218219
c, err := blowfish.NewSaltedCipher(ckey, csalt)
219220
if err != nil {

bcrypt/bcrypt_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,20 @@ func BenchmarkGeneration(b *testing.B) {
224224
GenerateFromPassword(passwd, 10)
225225
}
226226
}
227+
228+
// See Issue https://github.com/golang/go/issues/20425.
229+
func TestNoSideEffectsFromCompare(t *testing.T) {
230+
source := []byte("passw0rd123456")
231+
password := source[:len(source)-6]
232+
token := source[len(source)-6:]
233+
want := make([]byte, len(source))
234+
copy(want, source)
235+
236+
wantHash := []byte("$2a$10$LK9XRuhNxHHCvjX3tdkRKei1QiCDUKrJRhZv7WWZPuQGRUM92rOUa")
237+
_ = CompareHashAndPassword(wantHash, password)
238+
239+
got := bytes.Join([][]byte{password, token}, []byte(""))
240+
if !bytes.Equal(got, want) {
241+
t.Errorf("got=%q want=%q", got, want)
242+
}
243+
}

0 commit comments

Comments
 (0)