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

79 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

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 

5import abc 

6import typing 

7 

8from cryptography import utils 

9from cryptography.hazmat.primitives.hashes import HashAlgorithm 

10 

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

12# from the serialization module. 

13 

14 

15class PBES(utils.Enum): 

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

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

18 

19 

20class Encoding(utils.Enum): 

21 PEM = "PEM" 

22 DER = "DER" 

23 OpenSSH = "OpenSSH" 

24 Raw = "Raw" 

25 X962 = "ANSI X9.62" 

26 SMIME = "S/MIME" 

27 

28 

29class PrivateFormat(utils.Enum): 

30 PKCS8 = "PKCS8" 

31 TraditionalOpenSSL = "TraditionalOpenSSL" 

32 Raw = "Raw" 

33 OpenSSH = "OpenSSH" 

34 PKCS12 = "PKCS12" 

35 

36 def encryption_builder(self) -> "KeySerializationEncryptionBuilder": 

37 if self not in (PrivateFormat.OpenSSH, PrivateFormat.PKCS12): 

38 raise ValueError( 

39 "encryption_builder only supported with PrivateFormat.OpenSSH" 

40 " and PrivateFormat.PKCS12" 

41 ) 

42 return KeySerializationEncryptionBuilder(self) 

43 

44 

45class PublicFormat(utils.Enum): 

46 SubjectPublicKeyInfo = "X.509 subjectPublicKeyInfo with PKCS#1" 

47 PKCS1 = "Raw PKCS#1" 

48 OpenSSH = "OpenSSH" 

49 Raw = "Raw" 

50 CompressedPoint = "X9.62 Compressed Point" 

51 UncompressedPoint = "X9.62 Uncompressed Point" 

52 

53 

54class ParameterFormat(utils.Enum): 

55 PKCS3 = "PKCS3" 

56 

57 

58class KeySerializationEncryption(metaclass=abc.ABCMeta): 

59 pass 

60 

61 

62class BestAvailableEncryption(KeySerializationEncryption): 

63 def __init__(self, password: bytes): 

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

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

66 

67 self.password = password 

68 

69 

70class NoEncryption(KeySerializationEncryption): 

71 pass 

72 

73 

74class KeySerializationEncryptionBuilder(object): 

75 def __init__( 

76 self, 

77 format: PrivateFormat, 

78 *, 

79 _kdf_rounds: typing.Optional[int] = None, 

80 _hmac_hash: typing.Optional[HashAlgorithm] = None, 

81 _key_cert_algorithm: typing.Optional[PBES] = None, 

82 ) -> None: 

83 self._format = format 

84 

85 self._kdf_rounds = _kdf_rounds 

86 self._hmac_hash = _hmac_hash 

87 self._key_cert_algorithm = _key_cert_algorithm 

88 

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

90 if self._kdf_rounds is not None: 

91 raise ValueError("kdf_rounds already set") 

92 

93 if not isinstance(rounds, int): 

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

95 

96 if rounds < 1: 

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

98 

99 return KeySerializationEncryptionBuilder( 

100 self._format, 

101 _kdf_rounds=rounds, 

102 _hmac_hash=self._hmac_hash, 

103 _key_cert_algorithm=self._key_cert_algorithm, 

104 ) 

105 

106 def hmac_hash( 

107 self, algorithm: HashAlgorithm 

108 ) -> "KeySerializationEncryptionBuilder": 

109 if self._format is not PrivateFormat.PKCS12: 

110 raise TypeError( 

111 "hmac_hash only supported with PrivateFormat.PKCS12" 

112 ) 

113 

114 if self._hmac_hash is not None: 

115 raise ValueError("hmac_hash already set") 

116 return KeySerializationEncryptionBuilder( 

117 self._format, 

118 _kdf_rounds=self._kdf_rounds, 

119 _hmac_hash=algorithm, 

120 _key_cert_algorithm=self._key_cert_algorithm, 

121 ) 

122 

123 def key_cert_algorithm( 

124 self, algorithm: PBES 

125 ) -> "KeySerializationEncryptionBuilder": 

126 if self._format is not PrivateFormat.PKCS12: 

127 raise TypeError( 

128 "key_cert_algorithm only supported with " 

129 "PrivateFormat.PKCS12" 

130 ) 

131 if self._key_cert_algorithm is not None: 

132 raise ValueError("key_cert_algorithm already set") 

133 return KeySerializationEncryptionBuilder( 

134 self._format, 

135 _kdf_rounds=self._kdf_rounds, 

136 _hmac_hash=self._hmac_hash, 

137 _key_cert_algorithm=algorithm, 

138 ) 

139 

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

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

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

143 

144 return _KeySerializationEncryption( 

145 self._format, 

146 password, 

147 kdf_rounds=self._kdf_rounds, 

148 hmac_hash=self._hmac_hash, 

149 key_cert_algorithm=self._key_cert_algorithm, 

150 ) 

151 

152 

153class _KeySerializationEncryption(KeySerializationEncryption): 

154 def __init__( 

155 self, 

156 format: PrivateFormat, 

157 password: bytes, 

158 *, 

159 kdf_rounds: typing.Optional[int], 

160 hmac_hash: typing.Optional[HashAlgorithm], 

161 key_cert_algorithm: typing.Optional[PBES], 

162 ): 

163 self._format = format 

164 self.password = password 

165 

166 self._kdf_rounds = kdf_rounds 

167 self._hmac_hash = hmac_hash 

168 self._key_cert_algorithm = key_cert_algorithm