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

112 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:36 +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 

5 

6import abc 

7import typing 

8 

9from cryptography.hazmat.primitives import _serialization 

10 

11_MIN_MODULUS_SIZE = 512 

12 

13 

14def generate_parameters( 

15 generator: int, key_size: int, backend: typing.Any = None 

16) -> "DHParameters": 

17 from cryptography.hazmat.backends.openssl.backend import backend as ossl 

18 

19 return ossl.generate_dh_parameters(generator, key_size) 

20 

21 

22class DHParameterNumbers: 

23 def __init__(self, p: int, g: int, q: typing.Optional[int] = None) -> None: 

24 if not isinstance(p, int) or not isinstance(g, int): 

25 raise TypeError("p and g must be integers") 

26 if q is not None and not isinstance(q, int): 

27 raise TypeError("q must be integer or None") 

28 

29 if g < 2: 

30 raise ValueError("DH generator must be 2 or greater") 

31 

32 if p.bit_length() < _MIN_MODULUS_SIZE: 

33 raise ValueError( 

34 f"p (modulus) must be at least {_MIN_MODULUS_SIZE}-bit" 

35 ) 

36 

37 self._p = p 

38 self._g = g 

39 self._q = q 

40 

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

42 if not isinstance(other, DHParameterNumbers): 

43 return NotImplemented 

44 

45 return ( 

46 self._p == other._p and self._g == other._g and self._q == other._q 

47 ) 

48 

49 def parameters(self, backend: typing.Any = None) -> "DHParameters": 

50 from cryptography.hazmat.backends.openssl.backend import ( 

51 backend as ossl, 

52 ) 

53 

54 return ossl.load_dh_parameter_numbers(self) 

55 

56 @property 

57 def p(self) -> int: 

58 return self._p 

59 

60 @property 

61 def g(self) -> int: 

62 return self._g 

63 

64 @property 

65 def q(self) -> typing.Optional[int]: 

66 return self._q 

67 

68 

69class DHPublicNumbers: 

70 def __init__(self, y: int, parameter_numbers: DHParameterNumbers) -> None: 

71 if not isinstance(y, int): 

72 raise TypeError("y must be an integer.") 

73 

74 if not isinstance(parameter_numbers, DHParameterNumbers): 

75 raise TypeError( 

76 "parameters must be an instance of DHParameterNumbers." 

77 ) 

78 

79 self._y = y 

80 self._parameter_numbers = parameter_numbers 

81 

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

83 if not isinstance(other, DHPublicNumbers): 

84 return NotImplemented 

85 

86 return ( 

87 self._y == other._y 

88 and self._parameter_numbers == other._parameter_numbers 

89 ) 

90 

91 def public_key(self, backend: typing.Any = None) -> "DHPublicKey": 

92 from cryptography.hazmat.backends.openssl.backend import ( 

93 backend as ossl, 

94 ) 

95 

96 return ossl.load_dh_public_numbers(self) 

97 

98 @property 

99 def y(self) -> int: 

100 return self._y 

101 

102 @property 

103 def parameter_numbers(self) -> DHParameterNumbers: 

104 return self._parameter_numbers 

105 

106 

107class DHPrivateNumbers: 

108 def __init__(self, x: int, public_numbers: DHPublicNumbers) -> None: 

109 if not isinstance(x, int): 

110 raise TypeError("x must be an integer.") 

111 

112 if not isinstance(public_numbers, DHPublicNumbers): 

113 raise TypeError( 

114 "public_numbers must be an instance of " "DHPublicNumbers." 

115 ) 

116 

117 self._x = x 

118 self._public_numbers = public_numbers 

119 

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

121 if not isinstance(other, DHPrivateNumbers): 

122 return NotImplemented 

123 

124 return ( 

125 self._x == other._x 

126 and self._public_numbers == other._public_numbers 

127 ) 

128 

129 def private_key(self, backend: typing.Any = None) -> "DHPrivateKey": 

130 from cryptography.hazmat.backends.openssl.backend import ( 

131 backend as ossl, 

132 ) 

133 

134 return ossl.load_dh_private_numbers(self) 

135 

136 @property 

137 def public_numbers(self) -> DHPublicNumbers: 

138 return self._public_numbers 

139 

140 @property 

141 def x(self) -> int: 

142 return self._x 

143 

144 

145class DHParameters(metaclass=abc.ABCMeta): 

146 @abc.abstractmethod 

147 def generate_private_key(self) -> "DHPrivateKey": 

148 """ 

149 Generates and returns a DHPrivateKey. 

150 """ 

151 

152 @abc.abstractmethod 

153 def parameter_bytes( 

154 self, 

155 encoding: _serialization.Encoding, 

156 format: _serialization.ParameterFormat, 

157 ) -> bytes: 

158 """ 

159 Returns the parameters serialized as bytes. 

160 """ 

161 

162 @abc.abstractmethod 

163 def parameter_numbers(self) -> DHParameterNumbers: 

164 """ 

165 Returns a DHParameterNumbers. 

166 """ 

167 

168 

169DHParametersWithSerialization = DHParameters 

170 

171 

172class DHPublicKey(metaclass=abc.ABCMeta): 

173 @property 

174 @abc.abstractmethod 

175 def key_size(self) -> int: 

176 """ 

177 The bit length of the prime modulus. 

178 """ 

179 

180 @abc.abstractmethod 

181 def parameters(self) -> DHParameters: 

182 """ 

183 The DHParameters object associated with this public key. 

184 """ 

185 

186 @abc.abstractmethod 

187 def public_numbers(self) -> DHPublicNumbers: 

188 """ 

189 Returns a DHPublicNumbers. 

190 """ 

191 

192 @abc.abstractmethod 

193 def public_bytes( 

194 self, 

195 encoding: _serialization.Encoding, 

196 format: _serialization.PublicFormat, 

197 ) -> bytes: 

198 """ 

199 Returns the key serialized as bytes. 

200 """ 

201 

202 

203DHPublicKeyWithSerialization = DHPublicKey 

204 

205 

206class DHPrivateKey(metaclass=abc.ABCMeta): 

207 @property 

208 @abc.abstractmethod 

209 def key_size(self) -> int: 

210 """ 

211 The bit length of the prime modulus. 

212 """ 

213 

214 @abc.abstractmethod 

215 def public_key(self) -> DHPublicKey: 

216 """ 

217 The DHPublicKey associated with this private key. 

218 """ 

219 

220 @abc.abstractmethod 

221 def parameters(self) -> DHParameters: 

222 """ 

223 The DHParameters object associated with this private key. 

224 """ 

225 

226 @abc.abstractmethod 

227 def exchange(self, peer_public_key: DHPublicKey) -> bytes: 

228 """ 

229 Given peer's DHPublicKey, carry out the key exchange and 

230 return shared key as bytes. 

231 """ 

232 

233 @abc.abstractmethod 

234 def private_numbers(self) -> DHPrivateNumbers: 

235 """ 

236 Returns a DHPrivateNumbers. 

237 """ 

238 

239 @abc.abstractmethod 

240 def private_bytes( 

241 self, 

242 encoding: _serialization.Encoding, 

243 format: _serialization.PrivateFormat, 

244 encryption_algorithm: _serialization.KeySerializationEncryption, 

245 ) -> bytes: 

246 """ 

247 Returns the key serialized as bytes. 

248 """ 

249 

250 

251DHPrivateKeyWithSerialization = DHPrivateKey