1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

bcrypt: fix issue #16769 security problem in compare_hash_and_password (#16815)

This commit is contained in:
mfont 2022-12-31 16:18:43 +01:00 committed by GitHub
parent 5daf39bc6a
commit 1e401d1433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 2 deletions

View File

@ -125,14 +125,18 @@ fn bcrypt(password []u8, cost int, salt []u8) ?[]u8 {
// expensive_blowfish_setup generate a Blowfish cipher, given key, cost and salt. // expensive_blowfish_setup generate a Blowfish cipher, given key, cost and salt.
fn expensive_blowfish_setup(key []u8, cost u32, salt []u8) ?&blowfish.Blowfish { fn expensive_blowfish_setup(key []u8, cost u32, salt []u8) ?&blowfish.Blowfish {
csalt := base64.decode(salt.bytestr()) csalt := base64.decode(salt.bytestr())
// Bug compatibility with C bcrypt implementations, which use the trailing NULL in the key string during expansion.
// See https://cs.opensource.google/go/x/crypto/+/master:bcrypt/bcrypt.go;l=226
mut ckey := key.clone()
ckey << 0
mut bf := blowfish.new_salted_cipher(key, csalt) or { return err } mut bf := blowfish.new_salted_cipher(ckey, csalt) or { return err }
mut i := u64(0) mut i := u64(0)
mut rounds := u64(0) mut rounds := u64(0)
rounds = 1 << cost rounds = 1 << cost
for i = 0; i < rounds; i++ { for i = 0; i < rounds; i++ {
blowfish.expand_key(key, mut bf) blowfish.expand_key(ckey, mut bf)
blowfish.expand_key(csalt, mut bf) blowfish.expand_key(csalt, mut bf)
} }

View File

@ -8,4 +8,14 @@ fn test_crypto_bcrypt() {
bcrypt.compare_hash_and_password('password2'.bytes(), hash.bytes()) or { bcrypt.compare_hash_and_password('password2'.bytes(), hash.bytes()) or {
assert err.msg() == 'mismatched hash and password' assert err.msg() == 'mismatched hash and password'
} }
hash2 := bcrypt.generate_from_password('bb'.bytes(), 10) or { panic(err) }
mut hash2_must_mismatch := false
bcrypt.compare_hash_and_password('bbb'.bytes(), hash2.bytes()) or {
hash2_must_mismatch = true
assert err.msg() == 'mismatched hash and password'
}
assert hash2_must_mismatch
} }