Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py: 49%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

71 statements  

1# This file is dual licensed under the terms of the Apache License, Version 

2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 

3# for complete details. 

4 

5from __future__ import annotations 

6 

7import abc 

8 

9from cryptography.hazmat.primitives import hashes 

10from cryptography.hazmat.primitives._asymmetric import ( 

11 AsymmetricPadding as AsymmetricPadding, 

12) 

13from cryptography.hazmat.primitives.asymmetric import rsa 

14 

15 

16class PKCS1v15(AsymmetricPadding): 

17 name = "EMSA-PKCS1-v1_5" 

18 

19 def __eq__(self, other: object) -> bool: 

20 if not isinstance(other, PKCS1v15): 

21 return NotImplemented 

22 

23 return True 

24 

25 

26class _MaxLength: 

27 "Sentinel value for `MAX_LENGTH`." 

28 

29 

30class _Auto: 

31 "Sentinel value for `AUTO`." 

32 

33 

34class _DigestLength: 

35 "Sentinel value for `DIGEST_LENGTH`." 

36 

37 

38class PSS(AsymmetricPadding): 

39 MAX_LENGTH = _MaxLength() 

40 AUTO = _Auto() 

41 DIGEST_LENGTH = _DigestLength() 

42 name = "EMSA-PSS" 

43 _salt_length: int | _MaxLength | _Auto | _DigestLength 

44 

45 def __init__( 

46 self, 

47 mgf: MGF, 

48 salt_length: int | _MaxLength | _Auto | _DigestLength, 

49 ) -> None: 

50 self._mgf = mgf 

51 

52 if not isinstance( 

53 salt_length, (int, _MaxLength, _Auto, _DigestLength) 

54 ): 

55 raise TypeError( 

56 "salt_length must be an integer, MAX_LENGTH, " 

57 "DIGEST_LENGTH, or AUTO" 

58 ) 

59 

60 if isinstance(salt_length, int) and salt_length < 0: 

61 raise ValueError("salt_length must be zero or greater.") 

62 

63 self._salt_length = salt_length 

64 

65 def __eq__(self, other: object) -> bool: 

66 if not isinstance(other, PSS): 

67 return NotImplemented 

68 

69 return ( 

70 self._mgf == other._mgf and self._salt_length == other._salt_length 

71 ) 

72 

73 @property 

74 def mgf(self) -> MGF: 

75 return self._mgf 

76 

77 

78class OAEP(AsymmetricPadding): 

79 name = "EME-OAEP" 

80 

81 def __init__( 

82 self, 

83 mgf: MGF, 

84 algorithm: hashes.HashAlgorithm, 

85 label: bytes | None, 

86 ): 

87 if not isinstance(algorithm, hashes.HashAlgorithm): 

88 raise TypeError("Expected instance of hashes.HashAlgorithm.") 

89 

90 self._mgf = mgf 

91 self._algorithm = algorithm 

92 self._label = label 

93 

94 def __eq__(self, other: object) -> bool: 

95 if not isinstance(other, OAEP): 

96 return NotImplemented 

97 

98 return ( 

99 self._mgf == other._mgf 

100 and self._algorithm == other._algorithm 

101 and self._label == other._label 

102 ) 

103 

104 @property 

105 def algorithm(self) -> hashes.HashAlgorithm: 

106 return self._algorithm 

107 

108 @property 

109 def mgf(self) -> MGF: 

110 return self._mgf 

111 

112 

113class MGF(metaclass=abc.ABCMeta): 

114 _algorithm: hashes.HashAlgorithm 

115 

116 

117class MGF1(MGF): 

118 def __init__(self, algorithm: hashes.HashAlgorithm): 

119 if not isinstance(algorithm, hashes.HashAlgorithm): 

120 raise TypeError("Expected instance of hashes.HashAlgorithm.") 

121 

122 self._algorithm = algorithm 

123 

124 def __eq__(self, other: object) -> bool: 

125 if not isinstance(other, MGF1): 

126 return NotImplemented 

127 

128 return self._algorithm == other._algorithm 

129 

130 

131def calculate_max_pss_salt_length( 

132 key: rsa.RSAPrivateKey | rsa.RSAPublicKey, 

133 hash_algorithm: hashes.HashAlgorithm, 

134) -> int: 

135 if not isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): 

136 raise TypeError("key must be an RSA public or private key") 

137 # bit length - 1 per RFC 3447 

138 emlen = (key.key_size + 6) // 8 

139 salt_length = emlen - hash_algorithm.digest_size - 2 

140 assert salt_length >= 0 

141 return salt_length