Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/bcrypt/__init__.py: 32%

38 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:36 +0000

1# Author:: Donald Stufft (<donald@stufft.io>) 

2# Copyright:: Copyright (c) 2013 Donald Stufft 

3# License:: Apache License, Version 2.0 

4# 

5# Licensed under the Apache License, Version 2.0 (the "License"); 

6# you may not use this file except in compliance with the License. 

7# You may obtain a copy of the License at 

8# 

9# http://www.apache.org/licenses/LICENSE-2.0 

10# 

11# Unless required by applicable law or agreed to in writing, software 

12# distributed under the License is distributed on an "AS IS" BASIS, 

13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

14# See the License for the specific language governing permissions and 

15# limitations under the License. 

16from __future__ import absolute_import 

17from __future__ import division 

18 

19import hmac 

20import os 

21import warnings 

22 

23from .__about__ import ( 

24 __author__, 

25 __copyright__, 

26 __email__, 

27 __license__, 

28 __summary__, 

29 __title__, 

30 __uri__, 

31 __version__, 

32) 

33from . import _bcrypt # noqa: I100 

34 

35 

36__all__ = [ 

37 "__title__", 

38 "__summary__", 

39 "__uri__", 

40 "__version__", 

41 "__author__", 

42 "__email__", 

43 "__license__", 

44 "__copyright__", 

45 "gensalt", 

46 "hashpw", 

47 "kdf", 

48 "checkpw", 

49] 

50 

51 

52def gensalt(rounds: int = 12, prefix: bytes = b"2b") -> bytes: 

53 if prefix not in (b"2a", b"2b"): 

54 raise ValueError("Supported prefixes are b'2a' or b'2b'") 

55 

56 if rounds < 4 or rounds > 31: 

57 raise ValueError("Invalid rounds") 

58 

59 salt = os.urandom(16) 

60 output = _bcrypt.encode_base64(salt) 

61 

62 return ( 

63 b"$" 

64 + prefix 

65 + b"$" 

66 + ("%2.2u" % rounds).encode("ascii") 

67 + b"$" 

68 + output 

69 ) 

70 

71 

72def hashpw(password: bytes, salt: bytes) -> bytes: 

73 if isinstance(password, str) or isinstance(salt, str): 

74 raise TypeError("Strings must be encoded before hashing") 

75 

76 # bcrypt originally suffered from a wraparound bug: 

77 # http://www.openwall.com/lists/oss-security/2012/01/02/4 

78 # This bug was corrected in the OpenBSD source by truncating inputs to 72 

79 # bytes on the updated prefix $2b$, but leaving $2a$ unchanged for 

80 # compatibility. However, pyca/bcrypt 2.0.0 *did* correctly truncate inputs 

81 # on $2a$, so we do it here to preserve compatibility with 2.0.0 

82 password = password[:72] 

83 

84 return _bcrypt.hashpass(password, salt) 

85 

86 

87def checkpw(password: bytes, hashed_password: bytes) -> bool: 

88 if isinstance(password, str) or isinstance(hashed_password, str): 

89 raise TypeError("Strings must be encoded before checking") 

90 

91 ret = hashpw(password, hashed_password) 

92 return hmac.compare_digest(ret, hashed_password) 

93 

94 

95def kdf( 

96 password: bytes, 

97 salt: bytes, 

98 desired_key_bytes: int, 

99 rounds: int, 

100 ignore_few_rounds: bool = False, 

101) -> bytes: 

102 if isinstance(password, str) or isinstance(salt, str): 

103 raise TypeError("Strings must be encoded before hashing") 

104 

105 if len(password) == 0 or len(salt) == 0: 

106 raise ValueError("password and salt must not be empty") 

107 

108 if desired_key_bytes <= 0 or desired_key_bytes > 512: 

109 raise ValueError("desired_key_bytes must be 1-512") 

110 

111 if rounds < 1: 

112 raise ValueError("rounds must be 1 or more") 

113 

114 if rounds < 50 and not ignore_few_rounds: 

115 # They probably think bcrypt.kdf()'s rounds parameter is logarithmic, 

116 # expecting this value to be slow enough (it probably would be if this 

117 # were bcrypt). Emit a warning. 

118 warnings.warn( 

119 ( 

120 "Warning: bcrypt.kdf() called with only {0} round(s). " 

121 "This few is not secure: the parameter is linear, like PBKDF2." 

122 ).format(rounds), 

123 UserWarning, 

124 stacklevel=2, 

125 ) 

126 

127 return _bcrypt.pbkdf(password, salt, rounds, desired_key_bytes)