allow null bytes in inputs (#328)
This commit is contained in:
parent
bdfaf730d4
commit
2b2e989f3e
@ -73,9 +73,6 @@ def hashpw(password: bytes, salt: bytes) -> bytes:
|
||||
if isinstance(password, str) or isinstance(salt, str):
|
||||
raise TypeError("Strings must be encoded before hashing")
|
||||
|
||||
if b"\x00" in password:
|
||||
raise ValueError("password may not contain NUL bytes")
|
||||
|
||||
# bcrypt originally suffered from a wraparound bug:
|
||||
# http://www.openwall.com/lists/oss-security/2012/01/02/4
|
||||
# This bug was corrected in the OpenBSD source by truncating inputs to 72
|
||||
@ -91,11 +88,6 @@ def checkpw(password: bytes, hashed_password: bytes) -> bool:
|
||||
if isinstance(password, str) or isinstance(hashed_password, str):
|
||||
raise TypeError("Strings must be encoded before checking")
|
||||
|
||||
if b"\x00" in password or b"\x00" in hashed_password:
|
||||
raise ValueError(
|
||||
"password and hashed_password may not contain NUL bytes"
|
||||
)
|
||||
|
||||
ret = hashpw(password, hashed_password)
|
||||
return hmac.compare_digest(ret, hashed_password)
|
||||
|
||||
|
||||
4
tests/reference/Makefile
Normal file
4
tests/reference/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
.PHONY: all
|
||||
|
||||
all:
|
||||
go build -v ./bcrypt_reference.go
|
||||
35
tests/reference/bcrypt_reference.go
Normal file
35
tests/reference/bcrypt_reference.go
Normal file
@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// provides access to the golang implementation of bcrypt, for reference:
|
||||
// "password" to hash is provided on stdin, cost parameter is an optional
|
||||
// command-line parameter
|
||||
|
||||
func main() {
|
||||
cost := bcrypt.MinCost
|
||||
if len(os.Args) > 1 {
|
||||
if parsed, err := strconv.Atoi(os.Args[1]); err == nil {
|
||||
cost = parsed
|
||||
}
|
||||
}
|
||||
|
||||
buf, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
out, err := bcrypt.GenerateFromPassword(buf, cost)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
os.Stdout.Write(out)
|
||||
os.Stdout.Write([]byte("\n"))
|
||||
}
|
||||
5
tests/reference/go.mod
Normal file
5
tests/reference/go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/pyca/bcrypt
|
||||
|
||||
go 1.17
|
||||
|
||||
require golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
|
||||
2
tests/reference/go.sum
Normal file
2
tests/reference/go.sum
Normal file
@ -0,0 +1,2 @@
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
@ -144,6 +144,20 @@ _test_vectors = [
|
||||
b"$2a$05$/OK.fbVrR/bpIqNJ5ianF.",
|
||||
b"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
|
||||
),
|
||||
(
|
||||
b"}>\xb3\xfe\xf1\x8b\xa0\xe6(\xa2Lzq\xc3P\x7f\xcc\xc8b{\xf9\x14\xf6"
|
||||
b"\xf6`\x81G5\xec\x1d\x87\x10\xbf\xa7\xe1}I7 \x96\xdfc\xf2\xbf\xb3Vh"
|
||||
b"\xdfM\x88q\xf7\xff\x1b\x82~z\x13\xdd\xe9\x84\x00\xdd4",
|
||||
b"$2b$10$keO.ZZs22YtygVF6BLfhGO",
|
||||
b"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd.",
|
||||
),
|
||||
(
|
||||
b"g7\r\x01\xf3\xd4\xd0\xa9JB^\x18\x007P\xb2N\xc7\x1c\xee\x87&\x83C"
|
||||
b"\x8b\xe8\x18\xc5>\x86\x14/\xd6\xcc\x1cJ\xde\xd7ix\xeb\xdeO\xef"
|
||||
b"\xe1i\xac\xcb\x03\x96v1' \xd6@.m\xa5!\xa0\xef\xc0(",
|
||||
b"$2a$04$tecY.9ylRInW/rAAzXCXPO",
|
||||
b"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG",
|
||||
),
|
||||
]
|
||||
|
||||
_2y_test_vectors = [
|
||||
@ -281,11 +295,10 @@ def test_hashpw_str_salt():
|
||||
|
||||
|
||||
def test_checkpw_nul_byte():
|
||||
with pytest.raises(ValueError):
|
||||
bcrypt.checkpw(
|
||||
b"abc\0def",
|
||||
b"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe",
|
||||
)
|
||||
bcrypt.checkpw(
|
||||
b"abc\0def",
|
||||
b"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe",
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
bcrypt.checkpw(
|
||||
@ -296,8 +309,13 @@ def test_checkpw_nul_byte():
|
||||
|
||||
def test_hashpw_nul_byte():
|
||||
salt = bcrypt.gensalt(4)
|
||||
with pytest.raises(ValueError):
|
||||
bcrypt.hashpw(b"abc\0def", salt)
|
||||
hashed = bcrypt.hashpw(b"abc\0def", salt)
|
||||
assert bcrypt.checkpw(b"abc\0def", hashed)
|
||||
# assert that we are sensitive to changes in the password after the first
|
||||
# null byte:
|
||||
assert not bcrypt.checkpw(b"abc\0deg", hashed)
|
||||
assert not bcrypt.checkpw(b"abc\0def\0", hashed)
|
||||
assert not bcrypt.checkpw(b"abc\0def\0\0", hashed)
|
||||
|
||||
|
||||
def test_checkpw_extra_data():
|
||||
|
||||
Loading…
Reference in New Issue
Block a user