Skip to content

Commit 1199712

Browse files
authored
Reject rounds=0 for SHA1 hashes (#361)
Port of firebase/firebase-admin-node#677
1 parent d625ddd commit 1199712

File tree

2 files changed

+48
-37
lines changed

2 files changed

+48
-37
lines changed

firebase_admin/_user_import.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,6 @@ def _hmac(cls, name, key):
282282
}
283283
return UserImportHash(name, data)
284284

285-
@classmethod
286-
def _basic_hash(cls, name, rounds):
287-
data = {'rounds': _auth_utils.validate_int(rounds, 'rounds', 0, 120000)}
288-
return UserImportHash(name, data)
289-
290285
@classmethod
291286
def hmac_sha512(cls, key):
292287
"""Creates a new HMAC SHA512 algorithm instance.
@@ -340,48 +335,56 @@ def md5(cls, rounds):
340335
"""Creates a new MD5 algorithm instance.
341336
342337
Args:
343-
rounds: Number of rounds. Must be an integer between 0 and 120000.
338+
rounds: Number of rounds. Must be an integer between 0 and 8192.
344339
345340
Returns:
346341
UserImportHash: A new ``UserImportHash``.
347342
"""
348-
return cls._basic_hash('MD5', rounds)
343+
return UserImportHash(
344+
'MD5',
345+
{'rounds': _auth_utils.validate_int(rounds, 'rounds', 0, 8192)})
349346

350347
@classmethod
351348
def sha1(cls, rounds):
352349
"""Creates a new SHA1 algorithm instance.
353350
354351
Args:
355-
rounds: Number of rounds. Must be an integer between 0 and 120000.
352+
rounds: Number of rounds. Must be an integer between 1 and 8192.
356353
357354
Returns:
358355
UserImportHash: A new ``UserImportHash``.
359356
"""
360-
return cls._basic_hash('SHA1', rounds)
357+
return UserImportHash(
358+
'SHA1',
359+
{'rounds': _auth_utils.validate_int(rounds, 'rounds', 1, 8192)})
361360

362361
@classmethod
363362
def sha256(cls, rounds):
364363
"""Creates a new SHA256 algorithm instance.
365364
366365
Args:
367-
rounds: Number of rounds. Must be an integer between 0 and 120000.
366+
rounds: Number of rounds. Must be an integer between 1 and 8192.
368367
369368
Returns:
370369
UserImportHash: A new ``UserImportHash``.
371370
"""
372-
return cls._basic_hash('SHA256', rounds)
371+
return UserImportHash(
372+
'SHA256',
373+
{'rounds': _auth_utils.validate_int(rounds, 'rounds', 1, 8192)})
373374

374375
@classmethod
375376
def sha512(cls, rounds):
376377
"""Creates a new SHA512 algorithm instance.
377378
378379
Args:
379-
rounds: Number of rounds. Must be an integer between 0 and 120000.
380+
rounds: Number of rounds. Must be an integer between 1 and 8192.
380381
381382
Returns:
382383
UserImportHash: A new ``UserImportHash``.
383384
"""
384-
return cls._basic_hash('SHA512', rounds)
385+
return UserImportHash(
386+
'SHA512',
387+
{'rounds': _auth_utils.validate_int(rounds, 'rounds', 1, 8192)})
385388

386389
@classmethod
387390
def pbkdf_sha1(cls, rounds):
@@ -393,7 +396,9 @@ def pbkdf_sha1(cls, rounds):
393396
Returns:
394397
UserImportHash: A new ``UserImportHash``.
395398
"""
396-
return cls._basic_hash('PBKDF_SHA1', rounds)
399+
return UserImportHash(
400+
'PBKDF_SHA1',
401+
{'rounds': _auth_utils.validate_int(rounds, 'rounds', 0, 120000)})
397402

398403
@classmethod
399404
def pbkdf2_sha256(cls, rounds):
@@ -405,7 +410,9 @@ def pbkdf2_sha256(cls, rounds):
405410
Returns:
406411
UserImportHash: A new ``UserImportHash``.
407412
"""
408-
return cls._basic_hash('PBKDF2_SHA256', rounds)
413+
return UserImportHash(
414+
'PBKDF2_SHA256',
415+
{'rounds': _auth_utils.validate_int(rounds, 'rounds', 0, 120000)})
409416

410417
@classmethod
411418
def scrypt(cls, key, rounds, memory_cost, salt_separator=None):

tests/test_user_mgt.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -933,31 +933,35 @@ def test_invalid_hmac(self, func, key):
933933
with pytest.raises(ValueError):
934934
func(key=key)
935935

936-
@pytest.mark.parametrize('func,name', [
937-
(auth.UserImportHash.sha512, 'SHA512'),
938-
(auth.UserImportHash.sha256, 'SHA256'),
939-
(auth.UserImportHash.sha1, 'SHA1'),
940-
(auth.UserImportHash.md5, 'MD5'),
941-
(auth.UserImportHash.pbkdf_sha1, 'PBKDF_SHA1'),
942-
(auth.UserImportHash.pbkdf2_sha256, 'PBKDF2_SHA256'),
936+
@pytest.mark.parametrize('func,name,rounds', [
937+
(auth.UserImportHash.md5, 'MD5', [0, 8192]),
938+
(auth.UserImportHash.sha1, 'SHA1', [1, 8192]),
939+
(auth.UserImportHash.sha256, 'SHA256', [1, 8192]),
940+
(auth.UserImportHash.sha512, 'SHA512', [1, 8192]),
941+
(auth.UserImportHash.pbkdf_sha1, 'PBKDF_SHA1', [0, 120000]),
942+
(auth.UserImportHash.pbkdf2_sha256, 'PBKDF2_SHA256', [0, 120000]),
943943
])
944-
def test_basic(self, func, name):
945-
basic = func(rounds=10)
946-
expected = {
947-
'hashAlgorithm': name,
948-
'rounds': 10,
949-
}
950-
assert basic.to_dict() == expected
951-
952-
@pytest.mark.parametrize('func', [
953-
auth.UserImportHash.sha512, auth.UserImportHash.sha256,
954-
auth.UserImportHash.sha1, auth.UserImportHash.md5,
955-
auth.UserImportHash.pbkdf_sha1, auth.UserImportHash.pbkdf2_sha256,
944+
def test_basic(self, func, name, rounds):
945+
for rnds in rounds:
946+
basic = func(rounds=rnds)
947+
expected = {
948+
'hashAlgorithm': name,
949+
'rounds': rnds,
950+
}
951+
assert basic.to_dict() == expected
952+
953+
@pytest.mark.parametrize('func,rounds', [
954+
(auth.UserImportHash.md5, INVALID_INTS + [-1, 8193]),
955+
(auth.UserImportHash.sha1, INVALID_INTS + [0, 8193]),
956+
(auth.UserImportHash.sha256, INVALID_INTS + [0, 8193]),
957+
(auth.UserImportHash.sha512, INVALID_INTS + [0, 8193]),
958+
(auth.UserImportHash.pbkdf_sha1, INVALID_INTS + [-1, 120001]),
959+
(auth.UserImportHash.pbkdf2_sha256, INVALID_INTS + [-1, 120001]),
956960
])
957-
@pytest.mark.parametrize('rounds', INVALID_INTS + [120001])
958961
def test_invalid_basic(self, func, rounds):
959-
with pytest.raises(ValueError):
960-
func(rounds=rounds)
962+
for rnds in rounds:
963+
with pytest.raises(ValueError):
964+
func(rounds=rnds)
961965

962966
def test_scrypt(self):
963967
scrypt = auth.UserImportHash.scrypt(

0 commit comments

Comments
 (0)