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

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

58 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 import utils 

10from cryptography.hazmat.bindings._rust import Encoding as Encoding 

11from cryptography.hazmat.bindings._rust import ( 

12 ParameterFormat as ParameterFormat, 

13) 

14from cryptography.hazmat.bindings._rust import PrivateFormat as PrivateFormat 

15from cryptography.hazmat.bindings._rust import PublicFormat as PublicFormat 

16from cryptography.hazmat.primitives.hashes import HashAlgorithm 

17 

18# This exists to break an import cycle. These classes are normally accessible 

19# from the serialization module. 

20 

21 

22class PBES(utils.Enum): 

23 PBESv1SHA1And3KeyTripleDESCBC = "PBESv1 using SHA1 and 3-Key TripleDES" 

24 PBESv2SHA256AndAES256CBC = "PBESv2 using SHA256 PBKDF2 and AES256 CBC" 

25 

26 

27class KeySerializationEncryption(metaclass=abc.ABCMeta): 

28 pass 

29 

30 

31class BestAvailableEncryption(KeySerializationEncryption): 

32 def __init__(self, password: bytes): 

33 if not isinstance(password, bytes) or len(password) == 0: 

34 raise ValueError("Password must be 1 or more bytes.") 

35 

36 self.password = password 

37 

38 

39class NoEncryption(KeySerializationEncryption): 

40 pass 

41 

42 

43class KeySerializationEncryptionBuilder: 

44 def __init__( 

45 self, 

46 format: PrivateFormat, 

47 *, 

48 _kdf_rounds: int | None = None, 

49 _hmac_hash: HashAlgorithm | None = None, 

50 _key_cert_algorithm: PBES | None = None, 

51 ) -> None: 

52 self._format = format 

53 

54 self._kdf_rounds = _kdf_rounds 

55 self._hmac_hash = _hmac_hash 

56 self._key_cert_algorithm = _key_cert_algorithm 

57 

58 def kdf_rounds(self, rounds: int) -> KeySerializationEncryptionBuilder: 

59 if self._kdf_rounds is not None: 

60 raise ValueError("kdf_rounds already set") 

61 

62 if not isinstance(rounds, int): 

63 raise TypeError("kdf_rounds must be an integer") 

64 

65 if rounds < 1: 

66 raise ValueError("kdf_rounds must be a positive integer") 

67 

68 return KeySerializationEncryptionBuilder( 

69 self._format, 

70 _kdf_rounds=rounds, 

71 _hmac_hash=self._hmac_hash, 

72 _key_cert_algorithm=self._key_cert_algorithm, 

73 ) 

74 

75 def hmac_hash( 

76 self, algorithm: HashAlgorithm 

77 ) -> KeySerializationEncryptionBuilder: 

78 if self._format is not PrivateFormat.PKCS12: 

79 raise TypeError( 

80 "hmac_hash only supported with PrivateFormat.PKCS12" 

81 ) 

82 

83 if self._hmac_hash is not None: 

84 raise ValueError("hmac_hash already set") 

85 return KeySerializationEncryptionBuilder( 

86 self._format, 

87 _kdf_rounds=self._kdf_rounds, 

88 _hmac_hash=algorithm, 

89 _key_cert_algorithm=self._key_cert_algorithm, 

90 ) 

91 

92 def key_cert_algorithm( 

93 self, algorithm: PBES 

94 ) -> KeySerializationEncryptionBuilder: 

95 if self._format is not PrivateFormat.PKCS12: 

96 raise TypeError( 

97 "key_cert_algorithm only supported with PrivateFormat.PKCS12" 

98 ) 

99 if self._key_cert_algorithm is not None: 

100 raise ValueError("key_cert_algorithm already set") 

101 return KeySerializationEncryptionBuilder( 

102 self._format, 

103 _kdf_rounds=self._kdf_rounds, 

104 _hmac_hash=self._hmac_hash, 

105 _key_cert_algorithm=algorithm, 

106 ) 

107 

108 def build(self, password: bytes) -> KeySerializationEncryption: 

109 if not isinstance(password, bytes) or len(password) == 0: 

110 raise ValueError("Password must be 1 or more bytes.") 

111 

112 return _KeySerializationEncryption( 

113 self._format, 

114 password, 

115 kdf_rounds=self._kdf_rounds, 

116 hmac_hash=self._hmac_hash, 

117 key_cert_algorithm=self._key_cert_algorithm, 

118 ) 

119 

120 

121class _KeySerializationEncryption(KeySerializationEncryption): 

122 def __init__( 

123 self, 

124 format: PrivateFormat, 

125 password: bytes, 

126 *, 

127 kdf_rounds: int | None, 

128 hmac_hash: HashAlgorithm | None, 

129 key_cert_algorithm: PBES | None, 

130 ): 

131 self._format = format 

132 self.password = password 

133 

134 self._kdf_rounds = kdf_rounds 

135 self._hmac_hash = hmac_hash 

136 self._key_cert_algorithm = key_cert_algorithm